提交 559fb51b 编写于 作者: S Scott Bardone 提交者: Jeff Garzik

Update Chelsio gige net driver.

- Use extern prefix for functions required.
- Removed a lot of wrappers, including t1_read/write_reg_4.
- Removed various macros, using native kernel calls now.
- Enumerated various #defines.
- Removed a lot of shared code which is not currently used in "NIC only" mode.
- Removed dead code.

Documentation/networking/cxgb.txt:
- Updated release notes for version 2.1.1

drivers/net/chelsio/ch_ethtool.h
- removed file, no longer using ETHTOOL namespace.

drivers/net/chelsio/common.h
- moved code from osdep.h to common.h
- added comment to #endif indicating which symbol it closes.

drivers/net/chelsio/cphy.h
- removed dead code.
- added comment to #endif indicating which symbol it closes.

drivers/net/chelsio/cxgb2.c
- use DMA_{32,64}BIT_MASK in include/linux/dma-mapping.h.
- removed unused code.
- use printk message for link info resembling drivers/net/mii.c.
- no longer using the MODULE_xxx namespace.
- no longer using "pci_" namespace.
- no longer using ETHTOOL namespace.

drivers/net/chelsio/cxgb2.h
- removed file, merged into common.h

drivers/net/chelsio/elmer0.h
- removed dead code.
- added various enums.
- added comment to #endif indicating which symbol it closes.

drivers/net/chelsio/espi.c
- removed various macros, using native kernel calls now.
- removed a lot of wrappers, including t1_read/write_reg_4.

drivers/net/chelsio/espi.h
- added comment to #endif indicating which symbol it closes.

drivers/net/chelsio/gmac.h
- added comment to #endif indicating which symbol it closes.

drivers/net/chelsio/mv88x201x.c
- changes to sync with Chelsio TOT.

drivers/net/chelsio/osdep.h
- removed file, consolidation. osdep was used to translate wrapper functions
  since our code supports multiple OSs. removed wrappers.

  drivers/net/chelsio/pm3393.c
  - removed various macros, using native kernel calls now.
  - removed a lot of wrappers, including t1_read/write_reg_4.
  - removed unused code.

  drivers/net/chelsio/regs.h
  - added a few register entries for future and current feature support.
  - added comment to #endif indicating which symbol it closes.

  drivers/net/chelsio/sge.c
  - rewrote large portion of scatter-gather engine to stabilize
  performance.
  - using u8/u16/u32 kernel types instead of __u8/__u16/__u32 compiler
  types.

  drivers/net/chelsio/sge.h
  - rewrote large portion of scatter-gather engine to stabilize
  performance.
  - added comment to #endif indicating which symbol it closes.

  drivers/net/chelsio/subr.c
  - merged tp.c into subr.c
  - removed various macros, using native kernel calls now.
  - removed a lot of wrappers, including t1_read/write_reg_4.
  - removed unused code.

  drivers/net/chelsio/suni1x10gexp_regs.h
  - modified copyright and authorship of file.
  - added comment to #endif indicating which symbol it closes.

  drivers/net/chelsio/tp.c
  - removed file, merged into subr.c.

  drivers/net/chelsio/tp.h
  - removed file.

  include/linux/pci_ids.h
  - patched to include PCI_VENDOR_ID_CHELSIO 0x1425, removed define from
  our code.
上级 a5324343
......@@ -2,9 +2,9 @@
Driver Release Notes for Linux
Version 2.1.0
Version 2.1.1
March 8, 2005
June 20, 2005
CONTENTS
========
......@@ -21,8 +21,7 @@ INTRODUCTION
This document describes the Linux driver for Chelsio 10Gb Ethernet Network
Controller. This driver supports the Chelsio N210 NIC and is backward
compatible with the Chelsio N110 model 10Gb NICs. This driver supports AMD64
and EM64T, and x86 systems.
compatible with the Chelsio N110 model 10Gb NICs.
FEATURES
......@@ -121,23 +120,17 @@ PERFORMANCE
Disabling SACK:
sysctl -w net.ipv4.tcp_sack=0
Setting TCP read buffers (min/default/max):
sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
Setting TCP write buffers (min/pressure/max):
sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
Setting TCP buffer space (min/pressure/max):
sysctl -w net.ipv4.tcp_mem="10000000 10000000 10000000"
Setting large number of incoming connection requests (2.6.x only):
Setting large number of incoming connection requests:
sysctl -w net.ipv4.tcp_max_syn_backlog=3000
Setting maximum receive socket buffer size:
sysctl -w net.core.rmem_max=524287
sysctl -w net.core.rmem_max=1024000
Setting maximum send socket buffer size:
sysctl -w net.core.wmem_max=524287
sysctl -w net.core.wmem_max=1024000
Set smp_affinity (on a multiprocessor system) to a single CPU:
echo 1 > /proc/irq/<interrupt_number>/smp_affinity
Setting default receive socket buffer size:
sysctl -w net.core.rmem_default=524287
......@@ -151,8 +144,14 @@ PERFORMANCE
Setting maximum backlog (# of unprocessed packets before kernel drops):
sysctl -w net.core.netdev_max_backlog=300000
Set smp_affinity (on a multiprocessor system) to a single CPU:
echo 00000001 > /proc/irq/<interrupt_number>/smp_affinity
Setting TCP read buffers (min/default/max):
sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
Setting TCP write buffers (min/pressure/max):
sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
Setting TCP buffer space (min/pressure/max):
sysctl -w net.ipv4.tcp_mem="10000000 10000000 10000000"
TCP window size for single connections:
The receive buffer (RX_WINDOW) size must be at least as large as the
......@@ -186,7 +185,7 @@ DRIVER MESSAGES
may be found in /var/log/messages.
Driver up:
Chelsio Network Driver - version 2.1.0
Chelsio Network Driver - version 2.1.1
NIC detected:
eth#: Chelsio N210 1x10GBaseX NIC (rev #), PCIX 133MHz/64-bit
......@@ -282,13 +281,44 @@ KNOWN ISSUES
the number of outstanding transactions, via BIOS configuration
programming of the PCI-X card, to the following:
Data Length (bytes): 2k
Total allowed outstanding transactions: 1
Data Length (bytes): 1k
Total allowed outstanding transactions: 2
Please refer to AMD 8131-HT/PCI-X Errata 26310 Rev 3.08 August 2004,
section 56, "133-MHz Mode Split Completion Data Corruption" for more
details with this bug and workarounds suggested by AMD.
It may be possible to work outside AMD's recommended PCI-X settings, try
increasing the Data Length to 2k bytes for increased performance. If you
have issues with these settings, please revert to the "safe" settings
and duplicate the problem before submitting a bug or asking for support.
NOTE: The default setting on most systems is 8 outstanding transactions
and 2k bytes data length.
4. On multiprocessor systems, it has been noted that an application which
is handling 10Gb networking can switch between CPUs causing degraded
and/or unstable performance.
If running on an SMP system and taking performance measurements, it
is suggested you either run the latest netperf-2.4.0+ or use a binding
tool such as Tim Hockin's procstate utilities (runon)
<http://www.hockin.org/~thockin/procstate/>.
Binding netserver and netperf (or other applications) to particular
CPUs will have a significant difference in performance measurements.
You may need to experiment which CPU to bind the application to in
order to achieve the best performance for your system.
If you are developing an application designed for 10Gb networking,
please keep in mind you may want to look at kernel functions
sched_setaffinity & sched_getaffinity to bind your application.
If you are just running user-space applications such as ftp, telnet,
etc., you may want to try the runon tool provided by Tim Hockin's
procstate utility. You could also try binding the interface to a
particular CPU: runon 0 ifup eth0
SUPPORT
=======
......
......@@ -7,6 +7,5 @@ obj-$(CONFIG_CHELSIO_T1) += cxgb.o
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS)
cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o mv88x201x.o
cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o
/*****************************************************************************
* *
* File: ch_ethtool.h *
* $Revision: 1.5 $ *
* $Date: 2005/03/23 07:15:58 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License, version 2, as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* *
* History: *
* *
****************************************************************************/
#ifndef __CHETHTOOL_LINUX_H__
#define __CHETHTOOL_LINUX_H__
/* TCB size in 32-bit words */
#define TCB_WORDS (TCB_SIZE / 4)
enum {
ETHTOOL_SETREG,
ETHTOOL_GETREG,
ETHTOOL_SETTPI,
ETHTOOL_GETTPI,
ETHTOOL_DEVUP,
ETHTOOL_GETMTUTAB,
ETHTOOL_SETMTUTAB,
ETHTOOL_GETMTU,
ETHTOOL_SET_PM,
ETHTOOL_GET_PM,
ETHTOOL_GET_TCAM,
ETHTOOL_SET_TCAM,
ETHTOOL_GET_TCB,
ETHTOOL_READ_TCAM_WORD,
};
struct ethtool_reg {
uint32_t cmd;
uint32_t addr;
uint32_t val;
};
struct ethtool_mtus {
uint32_t cmd;
uint16_t mtus[NMTUS];
};
struct ethtool_pm {
uint32_t cmd;
uint32_t tx_pg_sz;
uint32_t tx_num_pg;
uint32_t rx_pg_sz;
uint32_t rx_num_pg;
uint32_t pm_total;
};
struct ethtool_tcam {
uint32_t cmd;
uint32_t tcam_size;
uint32_t nservers;
uint32_t nroutes;
};
struct ethtool_tcb {
uint32_t cmd;
uint32_t tcb_index;
uint32_t tcb_data[TCB_WORDS];
};
struct ethtool_tcam_word {
uint32_t cmd;
uint32_t addr;
uint32_t buf[3];
};
#define SIOCCHETHTOOL SIOCDEVPRIVATE
#endif
/*****************************************************************************
* *
* File: common.h *
* $Revision: 1.5 $ *
* $Date: 2005/03/23 07:41:27 $ *
* $Revision: 1.21 $ *
* $Date: 2005/06/22 00:43:25 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,74 +36,101 @@
* *
****************************************************************************/
#ifndef CHELSIO_COMMON_H
#define CHELSIO_COMMON_H
#ifndef _CXGB_COMMON_H_
#define _CXGB_COMMON_H_
#include <linux/config.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/pci_ids.h>
#define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver"
#define DRV_NAME "cxgb"
#define DRV_VERSION "2.1.1"
#define PFX DRV_NAME ": "
#define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__)
#define CH_WARN(fmt, ...) printk(KERN_WARNING PFX fmt, ## __VA_ARGS__)
#define CH_ALERT(fmt, ...) printk(KERN_ALERT PFX fmt, ## __VA_ARGS__)
#define CH_DEVICE(devid, ssid, idx) \
{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
#define SUPPORTED_PAUSE (1 << 13)
#define SUPPORTED_LOOPBACK (1 << 15)
#define ADVERTISED_PAUSE (1 << 13)
#define ADVERTISED_ASYM_PAUSE (1 << 14)
typedef struct adapter adapter_t;
void t1_elmer0_ext_intr(adapter_t *adapter);
void t1_link_changed(adapter_t *adapter, int port_id, int link_status,
int speed, int duplex, int fc);
struct t1_rx_mode {
struct net_device *dev;
u32 idx;
struct dev_mc_list *list;
};
#define t1_rx_mode_promisc(rm) (rm->dev->flags & IFF_PROMISC)
#define t1_rx_mode_allmulti(rm) (rm->dev->flags & IFF_ALLMULTI)
#define t1_rx_mode_mc_cnt(rm) (rm->dev->mc_count)
#define DIMOF(x) (sizeof(x)/sizeof(x[0]))
static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
{
u8 *addr = 0;
if (rm->idx++ < rm->dev->mc_count) {
addr = rm->list->dmi_addr;
rm->list = rm->list->next;
}
return addr;
}
#define NMTUS 8
#define MAX_NPORTS 4
#define TCB_SIZE 128
#define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff
enum {
CHBT_BOARD_7500,
CHBT_BOARD_8000,
CHBT_BOARD_CHT101,
CHBT_BOARD_CHT110,
CHBT_BOARD_CHT210,
CHBT_BOARD_CHT204,
CHBT_BOARD_N110,
CHBT_BOARD_N210,
CHBT_BOARD_COUGAR,
CHBT_BOARD_6800,
CHBT_BOARD_SIMUL
CHBT_BOARD_N210
};
enum {
CHBT_TERM_FPGA,
CHBT_TERM_T1,
CHBT_TERM_T2,
CHBT_TERM_T3
CHBT_TERM_T2
};
enum {
CHBT_MAC_CHELSIO_A,
CHBT_MAC_IXF1010,
CHBT_MAC_PM3393,
CHBT_MAC_VSC7321,
CHBT_MAC_DUMMY
};
enum {
CHBT_PHY_88E1041,
CHBT_PHY_88E1111,
CHBT_PHY_88X2010,
CHBT_PHY_XPAK,
CHBT_PHY_MY3126,
CHBT_PHY_DUMMY
};
enum {
PAUSE_RX = 1,
PAUSE_TX = 2,
PAUSE_AUTONEG = 4
PAUSE_RX = 1 << 0,
PAUSE_TX = 1 << 1,
PAUSE_AUTONEG = 1 << 2
};
/* Revisions of T1 chip */
#define TERM_T1A 0
#define TERM_T1B 1
#define TERM_T2 3
struct tp_params {
unsigned int pm_size;
unsigned int cm_size;
unsigned int pm_rx_base;
unsigned int pm_tx_base;
unsigned int pm_rx_pg_size;
unsigned int pm_tx_pg_size;
unsigned int pm_rx_num_pgs;
unsigned int pm_tx_num_pgs;
unsigned int use_5tuple_mode;
enum {
TERM_T1A = 0,
TERM_T1B = 1,
TERM_T2 = 3
};
struct sge_params {
......@@ -118,17 +145,7 @@ struct sge_params {
unsigned int polling;
};
struct mc5_params {
unsigned int mode; /* selects MC5 width */
unsigned int nservers; /* size of server region */
unsigned int nroutes; /* size of routing region */
};
/* Default MC5 region sizes */
#define DEFAULT_SERVER_REGION_LEN 256
#define DEFAULT_RT_REGION_LEN 1024
struct pci_params {
struct chelsio_pci_params {
unsigned short speed;
unsigned char width;
unsigned char is_pcix;
......@@ -136,31 +153,14 @@ struct pci_params {
struct adapter_params {
struct sge_params sge;
struct mc5_params mc5;
struct tp_params tp;
struct pci_params pci;
struct chelsio_pci_params pci;
const struct board_info *brd_info;
unsigned short mtus[NMTUS];
unsigned int nports; /* # of ethernet ports */
unsigned int stats_update_period;
unsigned short chip_revision;
unsigned char chip_version;
unsigned char is_asic;
};
struct pci_err_cnt {
unsigned int master_parity_err;
unsigned int sig_target_abort;
unsigned int rcv_target_abort;
unsigned int rcv_master_abort;
unsigned int sig_sys_err;
unsigned int det_parity_err;
unsigned int pio_parity_err;
unsigned int wf_parity_err;
unsigned int rf_parity_err;
unsigned int cf_parity_err;
};
struct link_config {
......@@ -175,8 +175,60 @@ struct link_config {
unsigned char autoneg; /* autonegotiating? */
};
#define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff
struct cmac;
struct cphy;
struct port_info {
struct net_device *dev;
struct cmac *mac;
struct cphy *phy;
struct link_config link_config;
struct net_device_stats netstats;
};
struct sge;
struct peespi;
struct adapter {
u8 *regs;
struct pci_dev *pdev;
unsigned long registered_device_map;
unsigned long open_device_map;
unsigned long flags;
const char *name;
int msg_enable;
u32 mmio_len;
struct work_struct ext_intr_handler_task;
struct adapter_params params;
struct vlan_group *vlan_grp;
/* Terminator modules. */
struct sge *sge;
struct peespi *espi;
struct port_info port[MAX_NPORTS];
struct work_struct stats_update_task;
struct timer_list stats_update_timer;
struct semaphore mib_mutex;
spinlock_t tpi_lock;
spinlock_t work_lock;
/* guards async operations */
spinlock_t async_lock ____cacheline_aligned;
u32 slow_intr_mask;
};
enum { /* adapter flags */
FULL_INIT_DONE = 1 << 0,
TSO_CAPABLE = 1 << 2,
TCP_CSUM_CAPABLE = 1 << 3,
UDP_CSUM_CAPABLE = 1 << 4,
VLAN_ACCEL_CAPABLE = 1 << 5,
RX_CSUM_ENABLED = 1 << 6,
};
struct mdio_ops;
struct gmac;
......@@ -205,19 +257,8 @@ struct board_info {
const char *desc;
};
#include "osdep.h"
#ifndef PCI_VENDOR_ID_CHELSIO
#define PCI_VENDOR_ID_CHELSIO 0x1425
#endif
extern struct pci_device_id t1_pci_tbl[];
static inline int t1_is_asic(const adapter_t *adapter)
{
return adapter->params.is_asic;
}
static inline int adapter_matches_type(const adapter_t *adapter,
int version, int revision)
{
......@@ -245,25 +286,29 @@ static inline unsigned int core_ticks_per_usec(const adapter_t *adap)
return board_info(adap)->clock_core / 1000000;
}
int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value);
int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value);
extern int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value);
extern int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value);
void t1_interrupts_enable(adapter_t *adapter);
void t1_interrupts_disable(adapter_t *adapter);
void t1_interrupts_clear(adapter_t *adapter);
int elmer0_ext_intr_handler(adapter_t *adapter);
int t1_slow_intr_handler(adapter_t *adapter);
extern void t1_interrupts_enable(adapter_t *adapter);
extern void t1_interrupts_disable(adapter_t *adapter);
extern void t1_interrupts_clear(adapter_t *adapter);
extern int elmer0_ext_intr_handler(adapter_t *adapter);
extern int t1_slow_intr_handler(adapter_t *adapter);
int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct board_info *t1_get_board_info(unsigned int board_id);
const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
extern const struct board_info *t1_get_board_info(unsigned int board_id);
extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
unsigned short ssid);
int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
struct adapter_params *p);
int t1_init_hw_modules(adapter_t *adapter);
int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi);
void t1_free_sw_modules(adapter_t *adapter);
void t1_fatal_err(adapter_t *adapter);
#endif
extern int t1_init_hw_modules(adapter_t *adapter);
extern int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi);
extern void t1_free_sw_modules(adapter_t *adapter);
extern void t1_fatal_err(adapter_t *adapter);
extern void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable);
extern void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable);
extern void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable);
#endif /* _CXGB_COMMON_H_ */
/*****************************************************************************
* *
* File: cphy.h *
* $Revision: 1.4 $ *
* $Date: 2005/03/23 07:41:27 $ *
* $Revision: 1.7 $ *
* $Date: 2005/06/21 18:29:47 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,8 +36,8 @@
* *
****************************************************************************/
#ifndef CHELSIO_CPHY_H
#define CHELSIO_CPHY_H
#ifndef _CXGB_CPHY_H_
#define _CXGB_CPHY_H_
#include "common.h"
......@@ -142,9 +142,7 @@ struct gphy {
int (*reset)(adapter_t *adapter);
};
extern struct gphy t1_my3126_ops;
extern struct gphy t1_mv88e1xxx_ops;
extern struct gphy t1_xpak_ops;
extern struct gphy t1_mv88x201x_ops;
extern struct gphy t1_dummy_phy_ops;
#endif
#endif /* _CXGB_CPHY_H_ */
/*****************************************************************************
* *
* File: cpl5_cmd.h *
* $Revision: 1.4 $ *
* $Date: 2005/03/23 07:15:58 $ *
* $Revision: 1.6 $ *
* $Date: 2005/06/21 18:29:47 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,8 +36,8 @@
* *
****************************************************************************/
#ifndef _CPL5_CMD_H
#define _CPL5_CMD_H
#ifndef _CXGB_CPL5_CMD_H_
#define _CXGB_CPL5_CMD_H_
#include <asm/byteorder.h>
......@@ -59,12 +59,12 @@ enum { /* TX_PKT_LSO ethernet types */
};
struct cpl_rx_data {
__u32 rsvd0;
__u32 len;
__u32 seq;
__u16 urg;
__u8 rsvd1;
__u8 status;
u32 rsvd0;
u32 len;
u32 seq;
u16 urg;
u8 rsvd1;
u8 status;
};
/*
......@@ -73,73 +73,73 @@ struct cpl_rx_data {
* used so we break it into 2 16-bit parts to easily meet our alignment needs.
*/
struct cpl_tx_pkt {
__u8 opcode;
u8 opcode;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 iff:4;
__u8 ip_csum_dis:1;
__u8 l4_csum_dis:1;
__u8 vlan_valid:1;
__u8 rsvd:1;
u8 iff:4;
u8 ip_csum_dis:1;
u8 l4_csum_dis:1;
u8 vlan_valid:1;
u8 rsvd:1;
#else
__u8 rsvd:1;
__u8 vlan_valid:1;
__u8 l4_csum_dis:1;
__u8 ip_csum_dis:1;
__u8 iff:4;
u8 rsvd:1;
u8 vlan_valid:1;
u8 l4_csum_dis:1;
u8 ip_csum_dis:1;
u8 iff:4;
#endif
__u16 vlan;
__u16 len_hi;
__u16 len_lo;
u16 vlan;
u16 len_hi;
u16 len_lo;
};
struct cpl_tx_pkt_lso {
__u8 opcode;
u8 opcode;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 iff:4;
__u8 ip_csum_dis:1;
__u8 l4_csum_dis:1;
__u8 vlan_valid:1;
__u8 rsvd:1;
u8 iff:4;
u8 ip_csum_dis:1;
u8 l4_csum_dis:1;
u8 vlan_valid:1;
u8 rsvd:1;
#else
__u8 rsvd:1;
__u8 vlan_valid:1;
__u8 l4_csum_dis:1;
__u8 ip_csum_dis:1;
__u8 iff:4;
u8 rsvd:1;
u8 vlan_valid:1;
u8 l4_csum_dis:1;
u8 ip_csum_dis:1;
u8 iff:4;
#endif
__u16 vlan;
__u32 len;
u16 vlan;
u32 len;
__u32 rsvd2;
__u8 rsvd3;
u32 rsvd2;
u8 rsvd3;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 tcp_hdr_words:4;
__u8 ip_hdr_words:4;
u8 tcp_hdr_words:4;
u8 ip_hdr_words:4;
#else
__u8 ip_hdr_words:4;
__u8 tcp_hdr_words:4;
u8 ip_hdr_words:4;
u8 tcp_hdr_words:4;
#endif
__u16 eth_type_mss;
u16 eth_type_mss;
};
struct cpl_rx_pkt {
__u8 opcode;
u8 opcode;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 iff:4;
__u8 csum_valid:1;
__u8 bad_pkt:1;
__u8 vlan_valid:1;
__u8 rsvd:1;
u8 iff:4;
u8 csum_valid:1;
u8 bad_pkt:1;
u8 vlan_valid:1;
u8 rsvd:1;
#else
__u8 rsvd:1;
__u8 vlan_valid:1;
__u8 bad_pkt:1;
__u8 csum_valid:1;
__u8 iff:4;
u8 rsvd:1;
u8 vlan_valid:1;
u8 bad_pkt:1;
u8 csum_valid:1;
u8 iff:4;
#endif
__u16 csum;
__u16 vlan;
__u16 len;
u16 csum;
u16 vlan;
u16 len;
};
#endif
#endif /* _CXGB_CPL5_CMD_H_ */
/*****************************************************************************
* *
* File: cxgb2.c *
* $Revision: 1.11 $ *
* $Date: 2005/03/23 07:41:27 $ *
* $Revision: 1.25 $ *
* $Date: 2005/06/22 00:43:25 $ *
* Description: *
* Chelsio 10Gb Ethernet Driver. *
* *
......@@ -37,7 +37,6 @@
****************************************************************************/
#include "common.h"
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
......@@ -48,44 +47,56 @@
#include <linux/mii.h>
#include <linux/sockios.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/dma-mapping.h>
#include <asm/uaccess.h>
#include "ch_ethtool.h"
#include "cpl5_cmd.h"
#include "regs.h"
#include "gmac.h"
#include "cphy.h"
#include "sge.h"
#include "tp.h"
#include "espi.h"
#ifdef work_struct
#include <linux/tqueue.h>
#define INIT_WORK INIT_TQUEUE
#define schedule_work schedule_task
#define flush_scheduled_work flush_scheduled_tasks
static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
{
schedule_delayed_work(&ap->stats_update_task, secs * HZ);
mod_timer(&ap->stats_update_timer, jiffies + secs * HZ);
}
static inline void cancel_mac_stats_update(struct adapter *ap)
{
cancel_delayed_work(&ap->stats_update_task);
del_timer_sync(&ap->stats_update_timer);
flush_scheduled_tasks();
}
#if BITS_PER_LONG == 64 && !defined(CONFIG_X86_64)
# define FMT64 "l"
#else
# define FMT64 "ll"
#endif
/*
* Stats update timer for 2.4. It schedules a task to do the actual update as
* we need to access MAC statistics in process context.
*/
static void mac_stats_timer(unsigned long data)
{
struct adapter *ap = (struct adapter *)data;
# define DRV_TYPE ""
# define MODULE_DESC "Chelsio Network Driver"
schedule_task(&ap->stats_update_task);
}
#else
#include <linux/workqueue.h>
static char driver_name[] = DRV_NAME;
static char driver_string[] = "Chelsio " DRV_TYPE "Network Driver";
static char driver_version[] = "2.1.0";
static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
{
schedule_delayed_work(&ap->stats_update_task, secs * HZ);
}
#define PCI_DMA_64BIT ~0ULL
#define PCI_DMA_32BIT 0xffffffffULL
static inline void cancel_mac_stats_update(struct adapter *ap)
{
cancel_delayed_work(&ap->stats_update_task);
}
#endif
#define MAX_CMDQ_ENTRIES 16384
#define MAX_CMDQ1_ENTRIES 1024
......@@ -107,10 +118,9 @@ static char driver_version[] = "2.1.0";
*/
#define EEPROM_SIZE 32
MODULE_DESCRIPTION(MODULE_DESC);
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR("Chelsio Communications");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
static int dflt_msg_enable = DFLT_MSG_ENABLE;
......@@ -140,17 +150,17 @@ static void t1_set_rxmode(struct net_device *dev)
static void link_report(struct port_info *p)
{
if (!netif_carrier_ok(p->dev))
printk(KERN_INFO "%s: link is down\n", p->dev->name);
printk(KERN_INFO "%s: link down\n", p->dev->name);
else {
const char *s = "10 Mbps";
const char *s = "10Mbps";
switch (p->link_config.speed) {
case SPEED_10000: s = "10 Gbps"; break;
case SPEED_1000: s = "1000 Mbps"; break;
case SPEED_100: s = "100 Mbps"; break;
case SPEED_10000: s = "10Gbps"; break;
case SPEED_1000: s = "1000Mbps"; break;
case SPEED_100: s = "100Mbps"; break;
}
printk(KERN_INFO "%s: link is up at %s, %s duplex\n",
printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
p->dev->name, s,
p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
}
......@@ -186,10 +196,8 @@ static void link_start(struct port_info *p)
static void enable_hw_csum(struct adapter *adapter)
{
if (adapter->flags & TSO_CAPABLE)
t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
if (adapter->flags & UDP_CSUM_CAPABLE)
t1_tp_set_udp_checksum_offload(adapter->tp, 1);
t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */
t1_tp_set_tcp_checksum_offload(adapter, 1);
}
/*
......@@ -210,15 +218,13 @@ static int cxgb_up(struct adapter *adapter)
}
t1_interrupts_clear(adapter);
if ((err = request_irq(adapter->pdev->irq, &t1_interrupt, SA_SHIRQ,
adapter->name, adapter)))
if ((err = request_irq(adapter->pdev->irq,
t1_select_intr_handler(adapter), SA_SHIRQ,
adapter->name, adapter))) {
goto out_err;
}
t1_sge_start(adapter->sge);
t1_interrupts_enable(adapter);
err = 0;
out_err:
return err;
}
......@@ -371,15 +377,48 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"RxInternalMACRcvError",
"RxInRangeLengthErrors",
"RxOutOfRangeLengthField",
"RxFrameTooLongErrors"
"RxFrameTooLongErrors",
"TSO",
"VLANextractions",
"VLANinsertions",
"RxCsumGood",
"TxCsumOffload",
"RxDrops"
"respQ_empty",
"respQ_overflow",
"freelistQ_empty",
"pkt_too_big",
"pkt_mismatch",
"cmdQ_full0",
"cmdQ_full1",
"tx_ipfrags",
"tx_reg_pkts",
"tx_lso_pkts",
"tx_do_cksum",
"espi_DIP2ParityErr",
"espi_DIP4Err",
"espi_RxDrops",
"espi_TxDrops",
"espi_RxOvfl",
"espi_ParityErr"
};
#define T2_REGMAP_SIZE (3 * 1024)
static int get_regs_len(struct net_device *dev)
{
return T2_REGMAP_SIZE;
}
static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct adapter *adapter = dev->priv;
strcpy(info->driver, driver_name);
strcpy(info->version, driver_version);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
strcpy(info->bus_info, pci_name(adapter->pdev));
}
......@@ -401,8 +440,12 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
struct adapter *adapter = dev->priv;
struct cmac *mac = adapter->port[dev->if_port].mac;
const struct cmac_statistics *s;
const struct sge_port_stats *ss;
const struct sge_intr_counts *t;
s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
ss = t1_sge_get_port_stats(adapter->sge, dev->if_port);
t = t1_sge_get_intr_counts(adapter->sge);
*data++ = s->TxOctetsOK;
*data++ = s->TxOctetsBad;
......@@ -437,6 +480,48 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = s->RxInRangeLengthErrors;
*data++ = s->RxOutOfRangeLengthField;
*data++ = s->RxFrameTooLongErrors;
*data++ = ss->tso;
*data++ = ss->vlan_xtract;
*data++ = ss->vlan_insert;
*data++ = ss->rx_cso_good;
*data++ = ss->tx_cso;
*data++ = ss->rx_drops;
*data++ = (u64)t->respQ_empty;
*data++ = (u64)t->respQ_overflow;
*data++ = (u64)t->freelistQ_empty;
*data++ = (u64)t->pkt_too_big;
*data++ = (u64)t->pkt_mismatch;
*data++ = (u64)t->cmdQ_full[0];
*data++ = (u64)t->cmdQ_full[1];
*data++ = (u64)t->tx_ipfrags;
*data++ = (u64)t->tx_reg_pkts;
*data++ = (u64)t->tx_lso_pkts;
*data++ = (u64)t->tx_do_cksum;
}
static inline void reg_block_dump(struct adapter *ap, void *buf,
unsigned int start, unsigned int end)
{
u32 *p = buf + start;
for ( ; start <= end; start += sizeof(u32))
*p++ = readl(ap->regs + start);
}
static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *buf)
{
struct adapter *ap = dev->priv;
/*
* Version scheme: bits 0..9: chip version, bits 10..15: chip revision
*/
regs->version = 2;
memset(buf, 0, T2_REGMAP_SIZE);
reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
......@@ -645,22 +730,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
{
struct adapter *adapter = dev->priv;
unsigned int sge_coalesce_usecs = 0;
/*
* If RX coalescing is requested we use NAPI, otherwise interrupts.
* This choice can be made only when all ports and the TOE are off.
*/
if (adapter->open_device_map == 0)
adapter->params.sge.polling = c->use_adaptive_rx_coalesce;
sge_coalesce_usecs = adapter->params.sge.last_rx_coalesce_raw;
sge_coalesce_usecs /= board_info(adapter)->clock_core / 1000000;
if ( (adapter->params.sge.coalesce_enable && !c->use_adaptive_rx_coalesce) &&
(c->rx_coalesce_usecs == sge_coalesce_usecs) ) {
adapter->params.sge.rx_coalesce_usecs =
adapter->params.sge.default_rx_coalesce_usecs;
if (adapter->params.sge.polling) {
adapter->params.sge.rx_coalesce_usecs = 0;
} else {
adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
}
adapter->params.sge.last_rx_coalesce_raw = adapter->params.sge.rx_coalesce_usecs;
adapter->params.sge.last_rx_coalesce_raw *= (board_info(adapter)->clock_core / 1000000);
adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
return 0;
}
......@@ -669,12 +752,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
{
struct adapter *adapter = dev->priv;
if (adapter->params.sge.coalesce_enable) { /* Adaptive algorithm on */
c->rx_coalesce_usecs = adapter->params.sge.last_rx_coalesce_raw;
c->rx_coalesce_usecs /= board_info(adapter)->clock_core / 1000000;
} else {
c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
}
c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
return 0;
......@@ -682,9 +760,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
static int get_eeprom_len(struct net_device *dev)
{
struct adapter *adapter = dev->priv;
return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
return EEPROM_SIZE;
}
#define EEPROM_MAGIC(ap) \
......@@ -728,86 +804,22 @@ static struct ethtool_ops t1_ethtool_ops = {
.get_strings = get_strings,
.get_stats_count = get_stats_count,
.get_ethtool_stats = get_stats,
.get_regs_len = get_regs_len,
.get_regs = get_regs,
.get_tso = ethtool_op_get_tso,
.set_tso = set_tso,
};
static int ethtool_ioctl(struct net_device *dev, void *useraddr)
static void cxgb_proc_cleanup(struct adapter *adapter,
struct proc_dir_entry *dir)
{
u32 cmd;
struct adapter *adapter = dev->priv;
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
return -EFAULT;
switch (cmd) {
case ETHTOOL_SETREG: {
struct ethtool_reg edata;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if ((edata.addr & 3) != 0 || edata.addr >= adapter->mmio_len)
return -EINVAL;
if (edata.addr == A_ESPI_MISC_CONTROL)
t1_espi_set_misc_ctrl(adapter, edata.val);
else {
if (edata.addr == 0x950)
t1_sge_set_ptimeout(adapter, edata.val);
else
writel(edata.val, adapter->regs + edata.addr);
}
break;
}
case ETHTOOL_GETREG: {
struct ethtool_reg edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if ((edata.addr & 3) != 0 || edata.addr >= adapter->mmio_len)
return -EINVAL;
if (edata.addr >= 0x900 && edata.addr <= 0x93c)
edata.val = t1_espi_get_mon(adapter, edata.addr, 1);
else {
if (edata.addr == 0x950)
edata.val = t1_sge_get_ptimeout(adapter);
else
edata.val = readl(adapter->regs + edata.addr);
}
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
break;
}
case ETHTOOL_SETTPI: {
struct ethtool_reg edata;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if ((edata.addr & 3) != 0)
return -EINVAL;
t1_tpi_write(adapter, edata.addr, edata.val);
break;
}
case ETHTOOL_GETTPI: {
struct ethtool_reg edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
if ((edata.addr & 3) != 0)
return -EINVAL;
t1_tpi_read(adapter, edata.addr, &edata.val);
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
break;
}
default:
return -EOPNOTSUPP;
}
return 0;
const char *name;
name = adapter->name;
remove_proc_entry(name, dir);
}
//#define chtoe_setup_toedev(adapter) NULL
#define update_mtu_tab(adapter)
#define write_smt_entry(adapter, idx)
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
......@@ -822,7 +834,8 @@ static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
struct cphy *phy = adapter->port[dev->if_port].phy;
u32 val;
if (!phy->mdio_read) return -EOPNOTSUPP;
if (!phy->mdio_read)
return -EOPNOTSUPP;
phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
&val);
data->val_out = val;
......@@ -831,15 +844,15 @@ static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
case SIOCSMIIREG: {
struct cphy *phy = adapter->port[dev->if_port].phy;
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (!phy->mdio_write) return -EOPNOTSUPP;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (!phy->mdio_write)
return -EOPNOTSUPP;
phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
data->val_in);
break;
}
case SIOCCHETHTOOL:
return ethtool_ioctl(dev, (void *)req->ifr_data);
default:
return -EOPNOTSUPP;
}
......@@ -902,9 +915,12 @@ static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
#ifdef CONFIG_NET_POLL_CONTROLLER
static void t1_netpoll(struct net_device *dev)
{
unsigned long flags;
struct adapter *adapter = dev->priv;
t1_interrupt(adapter->pdev->irq, adapter, NULL);
local_irq_save(flags);
t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL);
local_irq_restore(flags);
}
#endif
......@@ -938,16 +954,17 @@ static void mac_stats_task(void *data)
*/
static void ext_intr_task(void *data)
{
u32 enable;
struct adapter *adapter = data;
elmer0_ext_intr_handler(adapter);
/* Now reenable external interrupts */
t1_write_reg_4(adapter, A_PL_CAUSE, F_PL_INTR_EXT);
enable = t1_read_reg_4(adapter, A_PL_ENABLE);
t1_write_reg_4(adapter, A_PL_ENABLE, enable | F_PL_INTR_EXT);
spin_lock_irq(&adapter->async_lock);
adapter->slow_intr_mask |= F_PL_INTR_EXT;
writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
adapter->regs + A_PL_ENABLE);
spin_unlock_irq(&adapter->async_lock);
}
/*
......@@ -955,15 +972,14 @@ static void ext_intr_task(void *data)
*/
void t1_elmer0_ext_intr(struct adapter *adapter)
{
u32 enable = t1_read_reg_4(adapter, A_PL_ENABLE);
/*
* Schedule a task to handle external interrupts as we require
* a process context. We disable EXT interrupts in the interim
* and let the task reenable them when it's done.
*/
adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
t1_write_reg_4(adapter, A_PL_ENABLE, enable & ~F_PL_INTR_EXT);
writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
adapter->regs + A_PL_ENABLE);
schedule_work(&adapter->ext_intr_handler_task);
}
......@@ -977,7 +993,6 @@ void t1_fatal_err(struct adapter *adapter)
adapter->name);
}
static int __devinit init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
......@@ -990,8 +1005,8 @@ static int __devinit init_one(struct pci_dev *pdev,
struct port_info *pi;
if (!version_printed) {
printk(KERN_INFO "%s - version %s\n", driver_string,
driver_version);
printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
DRV_VERSION);
++version_printed;
}
......@@ -1006,20 +1021,22 @@ static int __devinit init_one(struct pci_dev *pdev,
goto out_disable_pdev;
}
if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) {
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
pci_using_dac = 1;
if (pci_set_consistent_dma_mask(pdev, PCI_DMA_64BIT)) {
if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
CH_ERR("%s: unable to obtain 64-bit DMA for"
"consistent allocations\n", pci_name(pdev));
err = -ENODEV;
goto out_disable_pdev;
}
} else if ((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT)) != 0) {
} else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
goto out_disable_pdev;
}
err = pci_request_regions(pdev, driver_name);
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
goto out_disable_pdev;
......@@ -1074,9 +1091,14 @@ static int __devinit init_one(struct pci_dev *pdev,
ext_intr_task, adapter);
INIT_WORK(&adapter->stats_update_task, mac_stats_task,
adapter);
#ifdef work_struct
init_timer(&adapter->stats_update_timer);
adapter->stats_update_timer.function = mac_stats_timer;
adapter->stats_update_timer.data =
(unsigned long)adapter;
#endif
pci_set_drvdata(pdev, netdev);
}
pi = &adapter->port[i];
......@@ -1088,11 +1110,12 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->priv = adapter;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
netdev->features |= NETIF_F_LLTX;
adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
if (vlan_tso_capable(adapter)) {
adapter->flags |= UDP_CSUM_CAPABLE;
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
adapter->flags |= VLAN_ACCEL_CAPABLE;
netdev->features |=
......@@ -1166,11 +1189,12 @@ static int __devinit init_one(struct pci_dev *pdev,
t1_free_sw_modules(adapter);
out_free_dev:
if (adapter) {
if (adapter->regs)
iounmap(adapter->regs);
if (adapter->regs) iounmap(adapter->regs);
for (i = bi->port_number - 1; i >= 0; --i)
if (adapter->port[i].dev)
free_netdev(adapter->port[i].dev);
if (adapter->port[i].dev) {
cxgb_proc_cleanup(adapter, proc_root_driver);
kfree(adapter->port[i].dev);
}
}
pci_release_regions(pdev);
out_disable_pdev:
......@@ -1200,8 +1224,10 @@ static void __devexit remove_one(struct pci_dev *pdev)
t1_free_sw_modules(adapter);
iounmap(adapter->regs);
while (--i >= 0)
if (adapter->port[i].dev)
free_netdev(adapter->port[i].dev);
if (adapter->port[i].dev) {
cxgb_proc_cleanup(adapter, proc_root_driver);
kfree(adapter->port[i].dev);
}
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
......@@ -1210,7 +1236,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
}
static struct pci_driver driver = {
.name = driver_name,
.name = DRV_NAME,
.id_table = t1_pci_tbl,
.probe = init_one,
.remove = __devexit_p(remove_one),
......@@ -1228,4 +1254,3 @@ static void __exit t1_cleanup_module(void)
module_init(t1_init_module);
module_exit(t1_cleanup_module);
/*****************************************************************************
* *
* File: cxgb2.h *
* $Revision: 1.8 $ *
* $Date: 2005/03/23 07:41:27 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License, version 2, as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* *
* History: *
* *
****************************************************************************/
#ifndef __CXGB_LINUX_H__
#define __CXGB_LINUX_H__
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/version.h>
#include <asm/semaphore.h>
#include <asm/bitops.h>
/* This belongs in if_ether.h */
#define ETH_P_CPL5 0xf
struct cmac;
struct cphy;
struct port_info {
struct net_device *dev;
struct cmac *mac;
struct cphy *phy;
struct link_config link_config;
struct net_device_stats netstats;
};
struct cxgbdev;
struct t1_sge;
struct pemc3;
struct pemc4;
struct pemc5;
struct peulp;
struct petp;
struct pecspi;
struct peespi;
struct work_struct;
struct vlan_group;
enum { /* adapter flags */
FULL_INIT_DONE = 0x1,
USING_MSI = 0x2,
TSO_CAPABLE = 0x4,
TCP_CSUM_CAPABLE = 0x8,
UDP_CSUM_CAPABLE = 0x10,
VLAN_ACCEL_CAPABLE = 0x20,
RX_CSUM_ENABLED = 0x40,
};
struct adapter {
u8 *regs;
struct pci_dev *pdev;
unsigned long registered_device_map;
unsigned long open_device_map;
unsigned int flags;
const char *name;
int msg_enable;
u32 mmio_len;
struct work_struct ext_intr_handler_task;
struct adapter_params params;
struct vlan_group *vlan_grp;
/* Terminator modules. */
struct sge *sge;
struct pemc3 *mc3;
struct pemc4 *mc4;
struct pemc5 *mc5;
struct petp *tp;
struct pecspi *cspi;
struct peespi *espi;
struct peulp *ulp;
struct port_info port[MAX_NPORTS];
struct work_struct stats_update_task;
struct timer_list stats_update_timer;
struct semaphore mib_mutex;
spinlock_t tpi_lock;
spinlock_t work_lock;
spinlock_t async_lock ____cacheline_aligned; /* guards async operations */
u32 slow_intr_mask;
};
#endif
/*****************************************************************************
* *
* File: elmer0.h *
* $Revision: 1.3 $ *
* $Date: 2005/03/23 07:15:58 $ *
* $Revision: 1.6 $ *
* $Date: 2005/06/21 22:49:43 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,14 +36,8 @@
* *
****************************************************************************/
#ifndef CHELSIO_ELMER0_H
#define CHELSIO_ELMER0_H
/* ELMER0 flavors */
enum {
ELMER0_XC2S300E_6FT256_C,
ELMER0_XC2S100E_6TQ144_C
};
#ifndef _CXGB_ELMER0_H_
#define _CXGB_ELMER0_H_
/* ELMER0 registers */
#define A_ELMER0_VERSION 0x100000
......@@ -154,4 +148,4 @@ enum {
#define MI1_OP_INDIRECT_READ_INC 2
#define MI1_OP_INDIRECT_READ 3
#endif
#endif /* _CXGB_ELMER0_H_ */
/*****************************************************************************
* *
* File: espi.c *
* $Revision: 1.9 $ *
* $Date: 2005/03/23 07:41:27 $ *
* $Revision: 1.14 $ *
* $Date: 2005/05/14 00:59:32 $ *
* Description: *
* Ethernet SPI functionality. *
* part of the Chelsio 10Gb Ethernet Driver. *
......@@ -63,15 +63,16 @@ static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr,
{
int busy, attempts = TRICN_CMD_ATTEMPTS;
t1_write_reg_4(adapter, A_ESPI_CMD_ADDR, V_WRITE_DATA(wr_data) |
writel(V_WRITE_DATA(wr_data) |
V_REGISTER_OFFSET(reg_offset) |
V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) |
V_BUNDLE_ADDR(bundle_addr) |
V_SPI4_COMMAND(TRICN_CMD_WRITE));
t1_write_reg_4(adapter, A_ESPI_GOSTAT, 0);
V_SPI4_COMMAND(TRICN_CMD_WRITE),
adapter->regs + A_ESPI_CMD_ADDR);
writel(0, adapter->regs + A_ESPI_GOSTAT);
do {
busy = t1_read_reg_4(adapter, A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY;
busy = readl(adapter->regs + A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY;
} while (busy && --attempts);
if (busy)
......@@ -99,12 +100,12 @@ static int tricn_init(adapter_t *adapter)
/* 1 */
timeout=1000;
do {
stat = t1_read_reg_4(adapter, A_ESPI_RX_RESET);
stat = readl(adapter->regs + A_ESPI_RX_RESET);
is_ready = (stat & 0x4);
timeout--;
udelay(5);
} while (!is_ready || (timeout==0));
t1_write_reg_4(adapter, A_ESPI_RX_RESET, 0x2);
writel(0x2, adapter->regs + A_ESPI_RX_RESET);
if (timeout==0)
{
CH_ERR("ESPI : ERROR : Timeout tricn_init() \n");
......@@ -127,14 +128,14 @@ static int tricn_init(adapter_t *adapter)
for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1);
/* 3 */
t1_write_reg_4(adapter, A_ESPI_RX_RESET, 0x3);
writel(0x3, adapter->regs + A_ESPI_RX_RESET);
return 0;
}
void t1_espi_intr_enable(struct peespi *espi)
{
u32 enable, pl_intr = t1_read_reg_4(espi->adapter, A_PL_ENABLE);
u32 enable, pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
/*
* Cannot enable ESPI interrupts on T1B because HW asserts the
......@@ -144,28 +145,28 @@ void t1_espi_intr_enable(struct peespi *espi)
* cannot be cleared (HW bug).
*/
enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK;
t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, enable);
t1_write_reg_4(espi->adapter, A_PL_ENABLE, pl_intr | F_PL_INTR_ESPI);
writel(enable, espi->adapter->regs + A_ESPI_INTR_ENABLE);
writel(pl_intr | F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
}
void t1_espi_intr_clear(struct peespi *espi)
{
t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, 0xffffffff);
t1_write_reg_4(espi->adapter, A_PL_CAUSE, F_PL_INTR_ESPI);
writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS);
writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE);
}
void t1_espi_intr_disable(struct peespi *espi)
{
u32 pl_intr = t1_read_reg_4(espi->adapter, A_PL_ENABLE);
u32 pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, 0);
t1_write_reg_4(espi->adapter, A_PL_ENABLE, pl_intr & ~F_PL_INTR_ESPI);
writel(0, espi->adapter->regs + A_ESPI_INTR_ENABLE);
writel(pl_intr & ~F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
}
int t1_espi_intr_handler(struct peespi *espi)
{
u32 cnt;
u32 status = t1_read_reg_4(espi->adapter, A_ESPI_INTR_STATUS);
u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
if (status & F_DIP4ERR)
espi->intr_cnt.DIP4_err++;
......@@ -184,7 +185,7 @@ int t1_espi_intr_handler(struct peespi *espi)
* Must read the error count to clear the interrupt
* that it causes.
*/
cnt = t1_read_reg_4(espi->adapter, A_ESPI_DIP2_ERR_COUNT);
cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
}
/*
......@@ -193,68 +194,28 @@ int t1_espi_intr_handler(struct peespi *espi)
*/
if (status && t1_is_T1B(espi->adapter))
status = 1;
t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, status);
writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
return 0;
}
static void espi_setup_for_pm3393(adapter_t *adapter)
const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi)
{
u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200;
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN0, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN1, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN2, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN3, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK, 0x100);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK, wmark);
t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 3);
t1_write_reg_4(adapter, A_ESPI_TRAIN, 0x08000008);
t1_write_reg_4(adapter, A_PORT_CONFIG,
V_RX_NPORTS(1) | V_TX_NPORTS(1));
return &espi->intr_cnt;
}
static void espi_setup_for_vsc7321(adapter_t *adapter)
static void espi_setup_for_pm3393(adapter_t *adapter)
{
u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200;
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN0, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN1, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN2, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN3, 0x1f4);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK, 0x100);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK, wmark);
t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 3);
t1_write_reg_4(adapter, A_ESPI_TRAIN, 0x08000008);
t1_write_reg_4(adapter, A_PORT_CONFIG,
V_RX_NPORTS(1) | V_TX_NPORTS(1));
}
/*
* Note that T1B requires at least 2 ports for IXF1010 due to a HW bug.
*/
static void espi_setup_for_ixf1010(adapter_t *adapter, int nports)
{
t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 1);
if (nports == 4) {
if (is_T2(adapter)) {
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
0xf00);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
0x3c0);
} else {
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
0x7ff);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
0x1ff);
}
} else {
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
0x1fff);
t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
0x7ff);
}
t1_write_reg_4(adapter, A_PORT_CONFIG,
V_RX_NPORTS(nports) | V_TX_NPORTS(nports));
writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0);
writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN1);
writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2);
writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN3);
writel(0x100, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
writel(wmark, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
writel(3, adapter->regs + A_ESPI_CALENDAR_LENGTH);
writel(0x08000008, adapter->regs + A_ESPI_TRAIN);
writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG);
}
/* T2 Init part -- */
......@@ -263,43 +224,42 @@ static void espi_setup_for_ixf1010(adapter_t *adapter, int nports)
/* 3. Init TriCN Hard Macro */
int t1_espi_init(struct peespi *espi, int mac_type, int nports)
{
u32 cnt;
u32 status_enable_extra = 0;
adapter_t *adapter = espi->adapter;
u32 cnt;
u32 status, burstval = 0x800100;
/* Disable ESPI training. MACs that can handle it enable it below. */
t1_write_reg_4(adapter, A_ESPI_TRAIN, 0);
writel(0, adapter->regs + A_ESPI_TRAIN);
if (is_T2(adapter)) {
t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL,
V_OUT_OF_SYNC_COUNT(4) |
V_DIP2_PARITY_ERR_THRES(3) | V_DIP4_THRES(1));
writel(V_OUT_OF_SYNC_COUNT(4) |
V_DIP2_PARITY_ERR_THRES(3) |
V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL);
if (nports == 4) {
/* T204: maxburst1 = 0x40, maxburst2 = 0x20 */
burstval = 0x200040;
}
}
t1_write_reg_4(adapter, A_ESPI_MAXBURST1_MAXBURST2, burstval);
writel(burstval, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
if (mac_type == CHBT_MAC_PM3393)
switch (mac_type) {
case CHBT_MAC_PM3393:
espi_setup_for_pm3393(adapter);
else if (mac_type == CHBT_MAC_VSC7321)
espi_setup_for_vsc7321(adapter);
else if (mac_type == CHBT_MAC_IXF1010) {
status_enable_extra = F_INTEL1010MODE;
espi_setup_for_ixf1010(adapter, nports);
} else
break;
default:
return -1;
}
/*
* Make sure any pending interrupts from the SPI are
* Cleared before enabling the interrupt.
*/
t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, ESPI_INTR_MASK);
status = t1_read_reg_4(espi->adapter, A_ESPI_INTR_STATUS);
writel(ESPI_INTR_MASK, espi->adapter->regs + A_ESPI_INTR_ENABLE);
status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
if (status & F_DIP2PARITYERR) {
cnt = t1_read_reg_4(espi->adapter, A_ESPI_DIP2_ERR_COUNT);
cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
}
/*
......@@ -308,10 +268,10 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
*/
if (status && t1_is_T1B(espi->adapter))
status = 1;
t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, status);
writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
t1_write_reg_4(adapter, A_ESPI_FIFO_STATUS_ENABLE,
status_enable_extra | F_RXSTATUSENABLE);
writel(status_enable_extra | F_RXSTATUSENABLE,
adapter->regs + A_ESPI_FIFO_STATUS_ENABLE);
if (is_T2(adapter)) {
tricn_init(adapter);
......@@ -319,10 +279,10 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
* Always position the control at the 1st port egress IN
* (sop,eop) counter to reduce PIOs for T/N210 workaround.
*/
espi->misc_ctrl = (t1_read_reg_4(adapter, A_ESPI_MISC_CONTROL)
espi->misc_ctrl = (readl(adapter->regs + A_ESPI_MISC_CONTROL)
& ~MON_MASK) | (F_MONITORED_DIRECTION
| F_MONITORED_INTERFACE);
t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, espi->misc_ctrl);
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
spin_lock_init(&espi->lock);
}
......@@ -354,15 +314,16 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
spin_lock(&espi->lock);
espi->misc_ctrl = (val & ~MON_MASK) |
(espi->misc_ctrl & MON_MASK);
t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, espi->misc_ctrl);
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
spin_unlock(&espi->lock);
}
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
{
struct peespi *espi = adapter->espi;
u32 sel;
struct peespi *espi = adapter->espi;
if (!is_T2(adapter))
return 0;
sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2);
......@@ -373,14 +334,13 @@ u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
else
spin_lock(&espi->lock);
if ((sel != (espi->misc_ctrl & MON_MASK))) {
t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL,
((espi->misc_ctrl & ~MON_MASK) | sel));
sel = t1_read_reg_4(adapter, A_ESPI_SCH_TOKEN3);
t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL,
espi->misc_ctrl);
writel(((espi->misc_ctrl & ~MON_MASK) | sel),
adapter->regs + A_ESPI_MISC_CONTROL);
sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
}
else
sel = t1_read_reg_4(adapter, A_ESPI_SCH_TOKEN3);
sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
spin_unlock(&espi->lock);
return sel;
}
/*****************************************************************************
* *
* File: espi.h *
* $Revision: 1.4 $ *
* $Date: 2005/03/23 07:15:58 $ *
* $Revision: 1.7 $ *
* $Date: 2005/06/21 18:29:47 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,8 +36,8 @@
* *
****************************************************************************/
#ifndef CHELSIO_ESPI_H
#define CHELSIO_ESPI_H
#ifndef _CXGB_ESPI_H_
#define _CXGB_ESPI_H_
#include "common.h"
......@@ -60,8 +60,9 @@ void t1_espi_intr_enable(struct peespi *);
void t1_espi_intr_clear(struct peespi *);
void t1_espi_intr_disable(struct peespi *);
int t1_espi_intr_handler(struct peespi *);
const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi);
void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val);
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait);
#endif
#endif /* _CXGB_ESPI_H_ */
/*****************************************************************************
* *
* File: gmac.h *
* $Revision: 1.3 $ *
* $Date: 2005/03/23 07:15:58 $ *
* $Revision: 1.6 $ *
* $Date: 2005/06/21 18:29:47 $ *
* Description: *
* Generic MAC functionality. *
* part of the Chelsio 10Gb Ethernet Driver. *
......@@ -37,8 +37,8 @@
* *
****************************************************************************/
#ifndef CHELSIO_GMAC_H
#define CHELSIO_GMAC_H
#ifndef _CXGB_GMAC_H_
#define _CXGB_GMAC_H_
#include "common.h"
......@@ -130,4 +130,5 @@ extern struct gmac t1_chelsio_mac_ops;
extern struct gmac t1_vsc7321_ops;
extern struct gmac t1_ixf1010_ops;
extern struct gmac t1_dummy_mac_ops;
#endif
#endif /* _CXGB_GMAC_H_ */
/*****************************************************************************
* *
* File: mv88x201x.c *
* $Revision: 1.7 $ *
* $Date: 2005/03/23 07:15:59 $ *
* $Revision: 1.12 $ *
* $Date: 2005/04/15 19:27:14 $ *
* Description: *
* Marvell PHY (mv88x201x) functionality. *
* part of the Chelsio 10Gb Ethernet Driver. *
......@@ -85,33 +85,29 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
static int mv88x201x_interrupt_enable(struct cphy *cphy)
{
u32 elmer;
/* Enable PHY LASI interrupts. */
mdio_write(cphy, 0x1, 0x9002, 0x1);
/* Enable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
u32 elmer;
t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
elmer |= ELMER0_GP_BIT6;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
}
return 0;
}
static int mv88x201x_interrupt_disable(struct cphy *cphy)
{
u32 elmer;
/* Disable PHY LASI interrupts. */
mdio_write(cphy, 0x1, 0x9002, 0x0);
/* Disable Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
u32 elmer;
t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
elmer &= ~ELMER0_GP_BIT6;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
}
return 0;
}
......@@ -144,11 +140,9 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
#endif
/* Clear Marvell interrupts through Elmer0. */
if (t1_is_asic(cphy->adapter)) {
t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
elmer |= ELMER0_GP_BIT6;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
}
return 0;
}
......
/*****************************************************************************
* *
* File: osdep.h *
* $Revision: 1.9 $ *
* $Date: 2005/03/23 07:41:27 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License, version 2, as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* *
* History: *
* *
****************************************************************************/
#ifndef __CHELSIO_OSDEP_H
#define __CHELSIO_OSDEP_H
#include <linux/version.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/init.h>
#include <asm/io.h>
#include "cxgb2.h"
#define DRV_NAME "cxgb"
#define PFX DRV_NAME ": "
#define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__)
#define CH_WARN(fmt, ...) printk(KERN_WARNING PFX fmt, ## __VA_ARGS__)
#define CH_ALERT(fmt, ...) printk(KERN_ALERT PFX fmt, ## __VA_ARGS__)
/*
* More powerful macro that selectively prints messages based on msg_enable.
* For info and debugging messages.
*/
#define CH_MSG(adapter, level, category, fmt, ...) do { \
if ((adapter)->msg_enable & NETIF_MSG_##category) \
printk(KERN_##level PFX "%s: " fmt, (adapter)->name, \
## __VA_ARGS__); \
} while (0)
#ifdef DEBUG
# define CH_DBG(adapter, category, fmt, ...) \
CH_MSG(adapter, DEBUG, category, fmt, ## __VA_ARGS__)
#else
# define CH_DBG(fmt, ...)
#endif
/* Additional NETIF_MSG_* categories */
#define NETIF_MSG_MMIO 0x8000000
#define CH_DEVICE(devid, ssid, idx) \
{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
#define SUPPORTED_PAUSE (1 << 13)
#define SUPPORTED_LOOPBACK (1 << 15)
#define ADVERTISED_PAUSE (1 << 13)
#define ADVERTISED_ASYM_PAUSE (1 << 14)
/*
* Now that we have included the driver's main data structure,
* we typedef it to something the rest of the system understands.
*/
typedef struct adapter adapter_t;
#define TPI_LOCK(adapter) spin_lock(&(adapter)->tpi_lock)
#define TPI_UNLOCK(adapter) spin_unlock(&(adapter)->tpi_lock)
void t1_elmer0_ext_intr(adapter_t *adapter);
void t1_link_changed(adapter_t *adapter, int port_id, int link_status,
int speed, int duplex, int fc);
static inline u16 t1_read_reg_2(adapter_t *adapter, u32 reg_addr)
{
u16 val = readw(adapter->regs + reg_addr);
CH_DBG(adapter, MMIO, "read register 0x%x value 0x%x\n", reg_addr,
val);
return val;
}
static inline void t1_write_reg_2(adapter_t *adapter, u32 reg_addr, u16 val)
{
CH_DBG(adapter, MMIO, "setting register 0x%x to 0x%x\n", reg_addr,
val);
writew(val, adapter->regs + reg_addr);
}
static inline u32 t1_read_reg_4(adapter_t *adapter, u32 reg_addr)
{
u32 val = readl(adapter->regs + reg_addr);
CH_DBG(adapter, MMIO, "read register 0x%x value 0x%x\n", reg_addr,
val);
return val;
}
static inline void t1_write_reg_4(adapter_t *adapter, u32 reg_addr, u32 val)
{
CH_DBG(adapter, MMIO, "setting register 0x%x to 0x%x\n", reg_addr,
val);
writel(val, adapter->regs + reg_addr);
}
static inline const char *port_name(adapter_t *adapter, int port_idx)
{
return adapter->port[port_idx].dev->name;
}
static inline void t1_set_hw_addr(adapter_t *adapter, int port_idx,
u8 hw_addr[])
{
memcpy(adapter->port[port_idx].dev->dev_addr, hw_addr, ETH_ALEN);
}
struct t1_rx_mode {
struct net_device *dev;
u32 idx;
struct dev_mc_list *list;
};
#define t1_rx_mode_promisc(rm) (rm->dev->flags & IFF_PROMISC)
#define t1_rx_mode_allmulti(rm) (rm->dev->flags & IFF_ALLMULTI)
#define t1_rx_mode_mc_cnt(rm) (rm->dev->mc_count)
static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
{
u8 *addr = 0;
if (rm->idx++ < rm->dev->mc_count) {
addr = rm->list->dmi_addr;
rm->list = rm->list->next;
}
return addr;
}
#endif
/*****************************************************************************
* *
* File: pm3393.c *
* $Revision: 1.9 $ *
* $Date: 2005/03/23 07:41:27 $ *
* $Revision: 1.16 $ *
* $Date: 2005/05/14 00:59:32 $ *
* Description: *
* PMC/SIERRA (pm3393) MAC-PHY functionality. *
* part of the Chelsio 10Gb Ethernet Driver. *
......@@ -45,15 +45,19 @@
/* 802.3ae 10Gb/s MDIO Manageable Device(MMD)
*/
#define MMD_RESERVED 0
#define MMD_PMAPMD 1
#define MMD_WIS 2
#define MMD_PCS 3
#define MMD_PHY_XGXS 4 /* XGMII Extender Sublayer */
#define MMD_DTE_XGXS 5
enum {
MMD_RESERVED,
MMD_PMAPMD,
MMD_WIS,
MMD_PCS,
MMD_PHY_XGXS, /* XGMII Extender Sublayer */
MMD_DTE_XGXS,
};
#define PHY_XGXS_CTRL_1 0
#define PHY_XGXS_STATUS_1 1
enum {
PHY_XGXS_CTRL_1,
PHY_XGXS_STATUS_1
};
#define OFFSET(REG_ADDR) (REG_ADDR << 2)
......@@ -160,9 +164,9 @@ static int pm3393_interrupt_enable(struct cmac *cmac)
0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ );
/* TERMINATOR - PL_INTERUPTS_EXT */
pl_intr = t1_read_reg_4(cmac->adapter, A_PL_ENABLE);
pl_intr = readl(cmac->adapter->regs + A_PL_ENABLE);
pl_intr |= F_PL_INTR_EXT;
t1_write_reg_4(cmac->adapter, A_PL_ENABLE, pl_intr);
writel(pl_intr, cmac->adapter->regs + A_PL_ENABLE);
return 0;
}
......@@ -242,9 +246,9 @@ static int pm3393_interrupt_clear(struct cmac *cmac)
/* TERMINATOR - PL_INTERUPTS_EXT
*/
pl_intr = t1_read_reg_4(cmac->adapter, A_PL_CAUSE);
pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE);
pl_intr |= F_PL_INTR_EXT;
t1_write_reg_4(cmac->adapter, A_PL_CAUSE, pl_intr);
writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE);
return 0;
}
......@@ -261,8 +265,6 @@ static int pm3393_interrupt_handler(struct cmac *cmac)
/* Read the master interrupt status register. */
pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
&master_intr_status);
CH_DBG(cmac->adapter, INTR, "PM3393 intr cause 0x%x\n",
master_intr_status);
/* TBD XXX Lets just clear everything for now */
pm3393_interrupt_clear(cmac);
......@@ -703,10 +705,9 @@ static struct cmac *pm3393_mac_create(adapter_t *adapter, int index)
t1_tpi_write(adapter, OFFSET(0x3040), 0x0c32); /* # TXXG Config */
/* For T1 use timer based Mac flow control. */
if (t1_is_T1B(adapter))
t1_tpi_write(adapter, OFFSET(0x304d), 0x8000);
t1_tpi_write(adapter, OFFSET(0x2040), 0x059c); /* # RXXG Config */
t1_tpi_write(adapter, OFFSET(0x2049), 0x0000); /* # RXXG Cut Through */
t1_tpi_write(adapter, OFFSET(0x2049), 0x0001); /* # RXXG Cut Through */
t1_tpi_write(adapter, OFFSET(0x2070), 0x0000); /* # Disable promiscuous mode */
/* Setup Exact Match Filter 0 to allow broadcast packets.
......@@ -814,12 +815,6 @@ static int pm3393_mac_reset(adapter_t * adapter)
successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
&& is_xaui_mabc_pll_locked);
CH_DBG(adapter, HW,
"PM3393 HW reset %d: pl4_reset 0x%x, val 0x%x, "
"is_pl4_outof_lock 0x%x, xaui_locked 0x%x\n",
i, is_pl4_reset_finished, val, is_pl4_outof_lock,
is_xaui_mabc_pll_locked);
}
return successful_reset ? 0 : 1;
}
......
/*****************************************************************************
* *
* File: regs.h *
* $Revision: 1.4 $ *
* $Date: 2005/03/23 07:15:59 $ *
* $Revision: 1.8 $ *
* $Date: 2005/06/21 18:29:48 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,7 +36,8 @@
* *
****************************************************************************/
/* Do not edit this file */
#ifndef _CXGB_REGS_H_
#define _CXGB_REGS_H_
/* SGE registers */
#define A_SG_CONTROL 0x0
......@@ -74,6 +75,14 @@
#define V_DISABLE_CMDQ1_GTS(x) ((x) << S_DISABLE_CMDQ1_GTS)
#define F_DISABLE_CMDQ1_GTS V_DISABLE_CMDQ1_GTS(1U)
#define S_DISABLE_FL0_GTS 10
#define V_DISABLE_FL0_GTS(x) ((x) << S_DISABLE_FL0_GTS)
#define F_DISABLE_FL0_GTS V_DISABLE_FL0_GTS(1U)
#define S_DISABLE_FL1_GTS 11
#define V_DISABLE_FL1_GTS(x) ((x) << S_DISABLE_FL1_GTS)
#define F_DISABLE_FL1_GTS V_DISABLE_FL1_GTS(1U)
#define S_ENABLE_BIG_ENDIAN 12
#define V_ENABLE_BIG_ENDIAN(x) ((x) << S_ENABLE_BIG_ENDIAN)
#define F_ENABLE_BIG_ENDIAN V_ENABLE_BIG_ENDIAN(1U)
......@@ -132,6 +141,7 @@
#define F_PACKET_MISMATCH V_PACKET_MISMATCH(1U)
#define A_SG_INT_CAUSE 0xbc
#define A_SG_RESPACCUTIMER 0xc0
/* MC3 registers */
......@@ -247,6 +257,10 @@
#define V_SYN_COOKIE_PARAMETER(x) ((x) << S_SYN_COOKIE_PARAMETER)
#define A_TP_PC_CONFIG 0x348
#define S_DIS_TX_FILL_WIN_PUSH 12
#define V_DIS_TX_FILL_WIN_PUSH(x) ((x) << S_DIS_TX_FILL_WIN_PUSH)
#define F_DIS_TX_FILL_WIN_PUSH V_DIS_TX_FILL_WIN_PUSH(1U)
#define S_TP_PC_REV 30
#define M_TP_PC_REV 0x3
#define G_TP_PC_REV(x) (((x) >> S_TP_PC_REV) & M_TP_PC_REV)
......@@ -451,3 +465,4 @@
#define M_PCI_MODE_CLK 0x3
#define G_PCI_MODE_CLK(x) (((x) >> S_PCI_MODE_CLK) & M_PCI_MODE_CLK)
#endif /* _CXGB_REGS_H_ */
此差异已折叠。
/*****************************************************************************
* *
* File: sge.h *
* $Revision: 1.7 $ *
* $Date: 2005/03/23 07:15:59 $ *
* $Revision: 1.11 $ *
* $Date: 2005/06/21 22:10:55 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
......@@ -36,25 +36,50 @@
* *
****************************************************************************/
#ifndef _CHELSIO_LINUX_SGE_H_
#define _CHELSIO_LINUX_SGE_H_
#ifndef _CXGB_SGE_H_
#define _CXGB_SGE_H_
#include <linux/types.h>
#include <linux/interrupt.h>
#include <asm/byteorder.h>
#ifndef IRQ_RETVAL
#define IRQ_RETVAL(x)
typedef void irqreturn_t;
#endif
typedef irqreturn_t (*intr_handler_t)(int, void *, struct pt_regs *);
struct sge_intr_counts {
unsigned int respQ_empty; /* # times respQ empty */
unsigned int respQ_overflow; /* # respQ overflow (fatal) */
unsigned int freelistQ_empty; /* # times freelist empty */
unsigned int pkt_too_big; /* packet too large (fatal) */
unsigned int pkt_mismatch;
unsigned int cmdQ_full[2]; /* not HW interrupt, host cmdQ[] full */
unsigned int cmdQ_full[3]; /* not HW IRQ, host cmdQ[] full */
unsigned int cmdQ_restarted[3];/* # of times cmdQ X was restarted */
unsigned int ethernet_pkts; /* # of Ethernet packets received */
unsigned int offload_pkts; /* # of offload packets received */
unsigned int offload_bundles; /* # of offload pkt bundles delivered */
unsigned int pure_rsps; /* # of non-payload responses */
unsigned int unhandled_irqs; /* # of unhandled interrupts */
unsigned int tx_ipfrags;
unsigned int tx_reg_pkts;
unsigned int tx_lso_pkts;
unsigned int tx_do_cksum;
};
struct sge_port_stats {
unsigned long rx_cso_good; /* # of successful RX csum offloads */
unsigned long tx_cso; /* # of TX checksum offloads */
unsigned long vlan_xtract; /* # of VLAN tag extractions */
unsigned long vlan_insert; /* # of VLAN tag extractions */
unsigned long tso; /* # of TSO requests */
unsigned long rx_drops; /* # of packets dropped due to no mem */
};
struct sk_buff;
struct net_device;
struct cxgbdev;
struct adapter;
struct sge_params;
struct sge;
......@@ -63,7 +88,9 @@ struct sge *t1_sge_create(struct adapter *, struct sge_params *);
int t1_sge_configure(struct sge *, struct sge_params *);
int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
void t1_sge_destroy(struct sge *);
irqreturn_t t1_interrupt(int, void *, struct pt_regs *);
intr_handler_t t1_select_intr_handler(adapter_t *adapter);
unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
unsigned int qid, struct net_device *netdev);
int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
void t1_set_vlan_accel(struct adapter *adapter, int on_off);
void t1_sge_start(struct sge *);
......@@ -72,8 +99,7 @@ int t1_sge_intr_error_handler(struct sge *);
void t1_sge_intr_enable(struct sge *);
void t1_sge_intr_disable(struct sge *);
void t1_sge_intr_clear(struct sge *);
const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge);
const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port);
void t1_sge_set_ptimeout(adapter_t *adapter, u32 val);
u32 t1_sge_get_ptimeout(adapter_t *adapter);
#endif /* _CHELSIO_LINUX_SGE_H_ */
#endif /* _CXGB_SGE_H_ */
此差异已折叠。
/*****************************************************************************
* *
* File: suni1x10gexp_regs.h *
* $Revision: 1.4 $ *
* $Date: 2005/03/23 07:15:59 $ *
* $Revision: 1.9 $ *
* $Date: 2005/06/22 00:17:04 $ *
* Description: *
* PMC/SIERRA (pm3393) MAC-PHY functionality. *
* part of the Chelsio 10Gb Ethernet Driver. *
......@@ -21,24 +21,16 @@
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* Authors: PMC/SIERRA *
* *
* History: *
* *
****************************************************************************/
#ifndef _SUNI1x10GEXP_REGS_H
#define _SUNI1x10GEXP_REGS_H
#ifndef _CXGB_SUNI1x10GEXP_REGS_H_
#define _CXGB_SUNI1x10GEXP_REGS_H_
/******************************************************************************/
/** S/UNI-1x10GE-XP REGISTER ADDRESS MAP **/
......@@ -217,5 +209,5 @@
#define SUNI1x10GEXP_BITMSK_TXXG_FCRX 0x0004
#define SUNI1x10GEXP_BITMSK_TXXG_PADEN 0x0002
#endif /* _SUNI1x10GEXP_REGS_H */
#endif /* _CXGB_SUNI1x10GEXP_REGS_H_ */
/*****************************************************************************
* *
* File: tp.c *
* $Revision: 1.6 $ *
* $Date: 2005/03/23 07:15:59 $ *
* Description: *
* Core ASIC Management. *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License, version 2, as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* *
* History: *
* *
****************************************************************************/
#include "common.h"
#include "regs.h"
#include "tp.h"
struct petp {
adapter_t *adapter;
};
/* Pause deadlock avoidance parameters */
#define DROP_MSEC 16
#define DROP_PKTS_CNT 1
static void tp_init(adapter_t *ap, const struct tp_params *p,
unsigned int tp_clk)
{
if (t1_is_asic(ap)) {
u32 val;
val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM |
F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET;
if (!p->pm_size)
val |= F_OFFLOAD_DISABLE;
else
val |= F_TP_IN_ESPI_CHECK_IP_CSUM |
F_TP_IN_ESPI_CHECK_TCP_CSUM;
t1_write_reg_4(ap, A_TP_IN_CONFIG, val);
t1_write_reg_4(ap, A_TP_OUT_CONFIG, F_TP_OUT_CSPI_CPL |
F_TP_OUT_ESPI_ETHERNET |
F_TP_OUT_ESPI_GENERATE_IP_CSUM |
F_TP_OUT_ESPI_GENERATE_TCP_CSUM);
t1_write_reg_4(ap, A_TP_GLOBAL_CONFIG, V_IP_TTL(64) |
F_PATH_MTU /* IP DF bit */ |
V_5TUPLE_LOOKUP(p->use_5tuple_mode) |
V_SYN_COOKIE_PARAMETER(29));
/*
* Enable pause frame deadlock prevention.
*/
if (is_T2(ap)) {
u32 drop_ticks = DROP_MSEC * (tp_clk / 1000);
t1_write_reg_4(ap, A_TP_TX_DROP_CONFIG,
F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR |
V_DROP_TICKS_CNT(drop_ticks) |
V_NUM_PKTS_DROPPED(DROP_PKTS_CNT));
}
}
}
void t1_tp_destroy(struct petp *tp)
{
kfree(tp);
}
struct petp * __devinit t1_tp_create(adapter_t *adapter, struct tp_params *p)
{
struct petp *tp = kmalloc(sizeof(*tp), GFP_KERNEL);
if (!tp)
return NULL;
memset(tp, 0, sizeof(*tp));
tp->adapter = adapter;
return tp;
}
void t1_tp_intr_enable(struct petp *tp)
{
u32 tp_intr = t1_read_reg_4(tp->adapter, A_PL_ENABLE);
{
/* We don't use any TP interrupts */
t1_write_reg_4(tp->adapter, A_TP_INT_ENABLE, 0);
t1_write_reg_4(tp->adapter, A_PL_ENABLE,
tp_intr | F_PL_INTR_TP);
}
}
void t1_tp_intr_disable(struct petp *tp)
{
u32 tp_intr = t1_read_reg_4(tp->adapter, A_PL_ENABLE);
{
t1_write_reg_4(tp->adapter, A_TP_INT_ENABLE, 0);
t1_write_reg_4(tp->adapter, A_PL_ENABLE,
tp_intr & ~F_PL_INTR_TP);
}
}
void t1_tp_intr_clear(struct petp *tp)
{
t1_write_reg_4(tp->adapter, A_TP_INT_CAUSE, 0xffffffff);
t1_write_reg_4(tp->adapter, A_PL_CAUSE, F_PL_INTR_TP);
}
int t1_tp_intr_handler(struct petp *tp)
{
u32 cause;
cause = t1_read_reg_4(tp->adapter, A_TP_INT_CAUSE);
t1_write_reg_4(tp->adapter, A_TP_INT_CAUSE, cause);
return 0;
}
static void set_csum_offload(struct petp *tp, u32 csum_bit, int enable)
{
u32 val = t1_read_reg_4(tp->adapter, A_TP_GLOBAL_CONFIG);
if (enable)
val |= csum_bit;
else
val &= ~csum_bit;
t1_write_reg_4(tp->adapter, A_TP_GLOBAL_CONFIG, val);
}
void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable)
{
set_csum_offload(tp, F_IP_CSUM, enable);
}
void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
{
set_csum_offload(tp, F_UDP_CSUM, enable);
}
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
{
set_csum_offload(tp, F_TCP_CSUM, enable);
}
/*
* Initialize TP state. tp_params contains initial settings for some TP
* parameters, particularly the one-time PM and CM settings.
*/
int t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk)
{
int busy = 0;
adapter_t *adapter = tp->adapter;
tp_init(adapter, p, tp_clk);
if (!busy)
t1_write_reg_4(adapter, A_TP_RESET, F_TP_RESET);
else
CH_ERR("%s: TP initialization timed out\n",
adapter->name);
return busy;
}
/*****************************************************************************
* *
* File: tp.h *
* $Revision: 1.3 $ *
* $Date: 2005/03/23 07:15:59 $ *
* Description: *
* part of the Chelsio 10Gb Ethernet Driver. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License, version 2, as *
* published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* http://www.chelsio.com *
* *
* Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
* All rights reserved. *
* *
* Maintainers: maintainers@chelsio.com *
* *
* Authors: Dimitrios Michailidis <dm@chelsio.com> *
* Tina Yang <tainay@chelsio.com> *
* Felix Marti <felix@chelsio.com> *
* Scott Bardone <sbardone@chelsio.com> *
* Kurt Ottaway <kottaway@chelsio.com> *
* Frank DiMambro <frank@chelsio.com> *
* *
* History: *
* *
****************************************************************************/
#ifndef CHELSIO_TP_H
#define CHELSIO_TP_H
#include "common.h"
#define TP_MAX_RX_COALESCING_SIZE 16224U
struct tp_mib_statistics {
/* IP */
u32 ipInReceive_hi;
u32 ipInReceive_lo;
u32 ipInHdrErrors_hi;
u32 ipInHdrErrors_lo;
u32 ipInAddrErrors_hi;
u32 ipInAddrErrors_lo;
u32 ipInUnknownProtos_hi;
u32 ipInUnknownProtos_lo;
u32 ipInDiscards_hi;
u32 ipInDiscards_lo;
u32 ipInDelivers_hi;
u32 ipInDelivers_lo;
u32 ipOutRequests_hi;
u32 ipOutRequests_lo;
u32 ipOutDiscards_hi;
u32 ipOutDiscards_lo;
u32 ipOutNoRoutes_hi;
u32 ipOutNoRoutes_lo;
u32 ipReasmTimeout;
u32 ipReasmReqds;
u32 ipReasmOKs;
u32 ipReasmFails;
u32 reserved[8];
/* TCP */
u32 tcpActiveOpens;
u32 tcpPassiveOpens;
u32 tcpAttemptFails;
u32 tcpEstabResets;
u32 tcpOutRsts;
u32 tcpCurrEstab;
u32 tcpInSegs_hi;
u32 tcpInSegs_lo;
u32 tcpOutSegs_hi;
u32 tcpOutSegs_lo;
u32 tcpRetransSeg_hi;
u32 tcpRetransSeg_lo;
u32 tcpInErrs_hi;
u32 tcpInErrs_lo;
u32 tcpRtoMin;
u32 tcpRtoMax;
};
struct petp;
struct tp_params;
struct petp *t1_tp_create(adapter_t *adapter, struct tp_params *p);
void t1_tp_destroy(struct petp *tp);
void t1_tp_intr_disable(struct petp *tp);
void t1_tp_intr_enable(struct petp *tp);
void t1_tp_intr_clear(struct petp *tp);
int t1_tp_intr_handler(struct petp *tp);
void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps);
void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable);
void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable);
int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size);
int t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk);
#endif
......@@ -2120,6 +2120,7 @@
#define PCI_DEVICE_ID_ENE_1225 0x1225
#define PCI_DEVICE_ID_ENE_1410 0x1410
#define PCI_DEVICE_ID_ENE_1420 0x1420
#define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_SYBA 0x1592
#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册