Commit f1d3d38a authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

[PATCH] chelsio: add support for other 10G boards

Add support for other versions of the 10G Chelsio boards.
This is basically a port of the vendor driver with the
TOE features removed.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 415294ec
...@@ -2361,9 +2361,9 @@ config CHELSIO_T1 ...@@ -2361,9 +2361,9 @@ config CHELSIO_T1
tristate "Chelsio 10Gb Ethernet support" tristate "Chelsio 10Gb Ethernet support"
depends on PCI depends on PCI
help help
This driver supports Chelsio N110 and N210 models 10Gb Ethernet This driver supports Chelsio gigabit and 10-gigabit
cards. More information about adapter features and performance Ethernet cards. More information about adapter features and
tuning is in <file:Documentation/networking/cxgb.txt>. performance tuning is in <file:Documentation/networking/cxgb.txt>.
For general information about Chelsio and our products, visit For general information about Chelsio and our products, visit
our website at <http://www.chelsio.com>. our website at <http://www.chelsio.com>.
......
# #
# Chelsio 10Gb NIC driver for Linux. # Chelsio T1 driver
# #
obj-$(CONFIG_CHELSIO_T1) += cxgb.o obj-$(CONFIG_CHELSIO_T1) += cxgb.o
EXTRA_CFLAGS += -Idrivers/net/chelsio $(DEBUG_FLAGS) cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \
mv88x201x.o my3126.o $(cxgb-y)
cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -53,13 +54,30 @@ ...@@ -53,13 +54,30 @@
#define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver" #define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver"
#define DRV_NAME "cxgb" #define DRV_NAME "cxgb"
#define DRV_VERSION "2.1.1" #define DRV_VERSION "2.2"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__) #define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__)
#define CH_WARN(fmt, ...) printk(KERN_WARNING 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_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
#define CH_DEVICE(devid, ssid, idx) \ #define CH_DEVICE(devid, ssid, idx) \
{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
...@@ -71,10 +89,6 @@ ...@@ -71,10 +89,6 @@
typedef struct adapter adapter_t; 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 t1_rx_mode {
struct net_device *dev; struct net_device *dev;
u32 idx; u32 idx;
...@@ -97,26 +111,53 @@ static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm) ...@@ -97,26 +111,53 @@ static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
} }
#define MAX_NPORTS 4 #define MAX_NPORTS 4
#define PORT_MASK ((1 << MAX_NPORTS) - 1)
#define NMTUS 8
#define TCB_SIZE 128
#define SPEED_INVALID 0xffff #define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff #define DUPLEX_INVALID 0xff
enum { enum {
CHBT_BOARD_N110, CHBT_BOARD_N110,
CHBT_BOARD_N210 CHBT_BOARD_N210,
CHBT_BOARD_7500,
CHBT_BOARD_8000,
CHBT_BOARD_CHT101,
CHBT_BOARD_CHT110,
CHBT_BOARD_CHT210,
CHBT_BOARD_CHT204,
CHBT_BOARD_CHT204V,
CHBT_BOARD_CHT204E,
CHBT_BOARD_CHN204,
CHBT_BOARD_COUGAR,
CHBT_BOARD_6800,
CHBT_BOARD_SIMUL,
}; };
enum { enum {
CHBT_TERM_FPGA,
CHBT_TERM_T1, CHBT_TERM_T1,
CHBT_TERM_T2 CHBT_TERM_T2,
CHBT_TERM_T3
}; };
enum { enum {
CHBT_MAC_CHELSIO_A,
CHBT_MAC_IXF1010,
CHBT_MAC_PM3393, CHBT_MAC_PM3393,
CHBT_MAC_VSC7321,
CHBT_MAC_DUMMY
}; };
enum { enum {
CHBT_PHY_88E1041,
CHBT_PHY_88E1111,
CHBT_PHY_88X2010, CHBT_PHY_88X2010,
CHBT_PHY_XPAK,
CHBT_PHY_MY3126,
CHBT_PHY_8244,
CHBT_PHY_DUMMY
}; };
enum { enum {
...@@ -150,16 +191,43 @@ struct chelsio_pci_params { ...@@ -150,16 +191,43 @@ struct chelsio_pci_params {
unsigned char is_pcix; unsigned char is_pcix;
}; };
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 rx_coalescing_size;
unsigned int use_5tuple_mode;
};
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 adapter_params { struct adapter_params {
struct sge_params sge; struct sge_params sge;
struct mc5_params mc5;
struct tp_params tp;
struct chelsio_pci_params pci; struct chelsio_pci_params pci;
const struct board_info *brd_info; const struct board_info *brd_info;
unsigned short mtus[NMTUS];
unsigned int nports; /* # of ethernet ports */ unsigned int nports; /* # of ethernet ports */
unsigned int stats_update_period; unsigned int stats_update_period;
unsigned short chip_revision; unsigned short chip_revision;
unsigned char chip_version; unsigned char chip_version;
unsigned char is_asic;
}; };
struct link_config { struct link_config {
...@@ -207,6 +275,7 @@ struct adapter { ...@@ -207,6 +275,7 @@ struct adapter {
/* Terminator modules. */ /* Terminator modules. */
struct sge *sge; struct sge *sge;
struct peespi *espi; struct peespi *espi;
struct petp *tp;
struct port_info port[MAX_NPORTS]; struct port_info port[MAX_NPORTS];
struct work_struct stats_update_task; struct work_struct stats_update_task;
...@@ -217,6 +286,7 @@ struct adapter { ...@@ -217,6 +286,7 @@ struct adapter {
/* guards async operations */ /* guards async operations */
spinlock_t async_lock ____cacheline_aligned; spinlock_t async_lock ____cacheline_aligned;
u32 slow_intr_mask; u32 slow_intr_mask;
int t1powersave;
}; };
enum { /* adapter flags */ enum { /* adapter flags */
...@@ -255,6 +325,11 @@ struct board_info { ...@@ -255,6 +325,11 @@ struct board_info {
const char *desc; const char *desc;
}; };
static inline int t1_is_asic(const adapter_t *adapter)
{
return adapter->params.is_asic;
}
extern struct pci_device_id t1_pci_tbl[]; extern struct pci_device_id t1_pci_tbl[];
static inline int adapter_matches_type(const adapter_t *adapter, static inline int adapter_matches_type(const adapter_t *adapter,
...@@ -284,13 +359,15 @@ static inline unsigned int core_ticks_per_usec(const adapter_t *adap) ...@@ -284,13 +359,15 @@ static inline unsigned int core_ticks_per_usec(const adapter_t *adap)
return board_info(adap)->clock_core / 1000000; return board_info(adap)->clock_core / 1000000;
} }
extern int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp);
extern int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value);
extern int t1_tpi_write(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); extern int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value);
extern void t1_interrupts_enable(adapter_t *adapter); extern void t1_interrupts_enable(adapter_t *adapter);
extern void t1_interrupts_disable(adapter_t *adapter); extern void t1_interrupts_disable(adapter_t *adapter);
extern void t1_interrupts_clear(adapter_t *adapter); extern void t1_interrupts_clear(adapter_t *adapter);
extern int elmer0_ext_intr_handler(adapter_t *adapter); extern int t1_elmer0_ext_intr_handler(adapter_t *adapter);
extern int t1_slow_intr_handler(adapter_t *adapter); extern int t1_slow_intr_handler(adapter_t *adapter);
extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
...@@ -304,9 +381,7 @@ extern int t1_init_hw_modules(adapter_t *adapter); ...@@ -304,9 +381,7 @@ extern int t1_init_hw_modules(adapter_t *adapter);
extern int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi); 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_free_sw_modules(adapter_t *adapter);
extern void t1_fatal_err(adapter_t *adapter); extern void t1_fatal_err(adapter_t *adapter);
extern void t1_link_changed(adapter_t *adapter, int port_id);
extern void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable); extern void t1_link_negotiated(adapter_t *adapter, int port_id, int link_stat,
extern void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable); int speed, int duplex, int pause);
extern void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable);
#endif /* _CXGB_COMMON_H_ */ #endif /* _CXGB_COMMON_H_ */
...@@ -52,7 +52,14 @@ struct mdio_ops { ...@@ -52,7 +52,14 @@ struct mdio_ops {
/* PHY interrupt types */ /* PHY interrupt types */
enum { enum {
cphy_cause_link_change = 0x1, cphy_cause_link_change = 0x1,
cphy_cause_error = 0x2 cphy_cause_error = 0x2,
cphy_cause_fifo_error = 0x3
};
enum {
PHY_LINK_UP = 0x1,
PHY_AUTONEG_RDY = 0x2,
PHY_AUTONEG_EN = 0x4
}; };
struct cphy; struct cphy;
...@@ -81,7 +88,18 @@ struct cphy_ops { ...@@ -81,7 +88,18 @@ struct cphy_ops {
/* A PHY instance */ /* A PHY instance */
struct cphy { struct cphy {
int addr; /* PHY address */ int addr; /* PHY address */
int state; /* Link status state machine */
adapter_t *adapter; /* associated adapter */ adapter_t *adapter; /* associated adapter */
struct work_struct phy_update;
u16 bmsr;
int count;
int act_count;
int act_on;
u32 elmer_gpo;
struct cphy_ops *ops; /* PHY operations */ struct cphy_ops *ops; /* PHY operations */
int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr, int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
int reg_addr, unsigned int *val); int reg_addr, unsigned int *val);
...@@ -142,6 +160,10 @@ struct gphy { ...@@ -142,6 +160,10 @@ struct gphy {
int (*reset)(adapter_t *adapter); int (*reset)(adapter_t *adapter);
}; };
extern struct gphy t1_my3126_ops;
extern struct gphy t1_mv88e1xxx_ops;
extern struct gphy t1_vsc8244_ops;
extern struct gphy t1_xpak_ops;
extern struct gphy t1_mv88x201x_ops; extern struct gphy t1_mv88x201x_ops;
extern struct gphy t1_dummy_phy_ops; extern struct gphy t1_dummy_phy_ops;
......
...@@ -46,24 +46,385 @@ ...@@ -46,24 +46,385 @@
#endif #endif
enum CPL_opcode { enum CPL_opcode {
CPL_PASS_OPEN_REQ = 0x1,
CPL_PASS_OPEN_RPL = 0x2,
CPL_PASS_ESTABLISH = 0x3,
CPL_PASS_ACCEPT_REQ = 0xE,
CPL_PASS_ACCEPT_RPL = 0x4,
CPL_ACT_OPEN_REQ = 0x5,
CPL_ACT_OPEN_RPL = 0x6,
CPL_CLOSE_CON_REQ = 0x7,
CPL_CLOSE_CON_RPL = 0x8,
CPL_CLOSE_LISTSRV_REQ = 0x9,
CPL_CLOSE_LISTSRV_RPL = 0xA,
CPL_ABORT_REQ = 0xB,
CPL_ABORT_RPL = 0xC,
CPL_PEER_CLOSE = 0xD,
CPL_ACT_ESTABLISH = 0x17,
CPL_GET_TCB = 0x24,
CPL_GET_TCB_RPL = 0x25,
CPL_SET_TCB = 0x26,
CPL_SET_TCB_FIELD = 0x27,
CPL_SET_TCB_RPL = 0x28,
CPL_PCMD = 0x29,
CPL_PCMD_READ = 0x31,
CPL_PCMD_READ_RPL = 0x32,
CPL_RX_DATA = 0xA0,
CPL_RX_DATA_DDP = 0xA1,
CPL_RX_DATA_ACK = 0xA3,
CPL_RX_PKT = 0xAD, CPL_RX_PKT = 0xAD,
CPL_RX_ISCSI_HDR = 0xAF,
CPL_TX_DATA_ACK = 0xB0,
CPL_TX_DATA = 0xB1,
CPL_TX_PKT = 0xB2, CPL_TX_PKT = 0xB2,
CPL_TX_PKT_LSO = 0xB6, CPL_TX_PKT_LSO = 0xB6,
CPL_RTE_DELETE_REQ = 0xC0,
CPL_RTE_DELETE_RPL = 0xC1,
CPL_RTE_WRITE_REQ = 0xC2,
CPL_RTE_WRITE_RPL = 0xD3,
CPL_RTE_READ_REQ = 0xC3,
CPL_RTE_READ_RPL = 0xC4,
CPL_L2T_WRITE_REQ = 0xC5,
CPL_L2T_WRITE_RPL = 0xD4,
CPL_L2T_READ_REQ = 0xC6,
CPL_L2T_READ_RPL = 0xC7,
CPL_SMT_WRITE_REQ = 0xC8,
CPL_SMT_WRITE_RPL = 0xD5,
CPL_SMT_READ_REQ = 0xC9,
CPL_SMT_READ_RPL = 0xCA,
CPL_ARP_MISS_REQ = 0xCD,
CPL_ARP_MISS_RPL = 0xCE,
CPL_MIGRATE_C2T_REQ = 0xDC,
CPL_MIGRATE_C2T_RPL = 0xDD,
CPL_ERROR = 0xD7,
/* internal: driver -> TOM */
CPL_MSS_CHANGE = 0xE1
}; };
enum { /* TX_PKT_LSO ethernet types */ #define NUM_CPL_CMDS 256
enum CPL_error {
CPL_ERR_NONE = 0,
CPL_ERR_TCAM_PARITY = 1,
CPL_ERR_TCAM_FULL = 3,
CPL_ERR_CONN_RESET = 20,
CPL_ERR_CONN_EXIST = 22,
CPL_ERR_ARP_MISS = 23,
CPL_ERR_BAD_SYN = 24,
CPL_ERR_CONN_TIMEDOUT = 30,
CPL_ERR_XMIT_TIMEDOUT = 31,
CPL_ERR_PERSIST_TIMEDOUT = 32,
CPL_ERR_FINWAIT2_TIMEDOUT = 33,
CPL_ERR_KEEPALIVE_TIMEDOUT = 34,
CPL_ERR_ABORT_FAILED = 42,
CPL_ERR_GENERAL = 99
};
enum {
CPL_CONN_POLICY_AUTO = 0,
CPL_CONN_POLICY_ASK = 1,
CPL_CONN_POLICY_DENY = 3
};
enum {
ULP_MODE_NONE = 0,
ULP_MODE_TCPDDP = 1,
ULP_MODE_ISCSI = 2,
ULP_MODE_IWARP = 3,
ULP_MODE_SSL = 4
};
enum {
CPL_PASS_OPEN_ACCEPT,
CPL_PASS_OPEN_REJECT
};
enum {
CPL_ABORT_SEND_RST = 0,
CPL_ABORT_NO_RST,
CPL_ABORT_POST_CLOSE_REQ = 2
};
enum { // TX_PKT_LSO ethernet types
CPL_ETH_II, CPL_ETH_II,
CPL_ETH_II_VLAN, CPL_ETH_II_VLAN,
CPL_ETH_802_3, CPL_ETH_802_3,
CPL_ETH_802_3_VLAN CPL_ETH_802_3_VLAN
}; };
struct cpl_rx_data { union opcode_tid {
u32 opcode_tid;
u8 opcode;
};
#define S_OPCODE 24
#define V_OPCODE(x) ((x) << S_OPCODE)
#define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF)
#define G_TID(x) ((x) & 0xFFFFFF)
/* tid is assumed to be 24-bits */
#define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid))
#define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid)
/* extract the TID from a CPL command */
#define GET_TID(cmd) (G_TID(ntohl(OPCODE_TID(cmd))))
struct tcp_options {
u16 mss;
u8 wsf;
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 rsvd:4;
u8 ecn:1;
u8 sack:1;
u8 tstamp:1;
#else
u8 tstamp:1;
u8 sack:1;
u8 ecn:1;
u8 rsvd:4;
#endif
};
struct cpl_pass_open_req {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 opt0h;
u32 opt0l;
u32 peer_netmask;
u32 opt1;
};
struct cpl_pass_open_rpl {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u8 resvd[7];
u8 status;
};
struct cpl_pass_establish {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 tos_tid;
u8 l2t_idx;
u8 rsvd[3];
u32 snd_isn;
u32 rcv_isn;
};
struct cpl_pass_accept_req {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 tos_tid;
struct tcp_options tcp_options;
u8 dst_mac[6];
u16 vlan_tag;
u8 src_mac[6];
u8 rsvd[2];
u32 rcv_isn;
u32 unknown_tcp_options;
};
struct cpl_pass_accept_rpl {
union opcode_tid ot;
u32 rsvd0;
u32 rsvd1;
u32 peer_ip;
u32 opt0h;
union {
u32 opt0l;
struct {
u8 rsvd[3];
u8 status;
};
};
};
struct cpl_act_open_req {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 opt0h;
u32 opt0l;
u32 iff_vlantag;
u32 rsvd;
};
struct cpl_act_open_rpl {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 new_tid;
u8 rsvd[3];
u8 status;
};
struct cpl_act_establish {
union opcode_tid ot;
u16 local_port;
u16 peer_port;
u32 local_ip;
u32 peer_ip;
u32 tos_tid;
u32 rsvd;
u32 snd_isn;
u32 rcv_isn;
};
struct cpl_get_tcb {
union opcode_tid ot;
u32 rsvd;
};
struct cpl_get_tcb_rpl {
union opcode_tid ot;
u16 len;
u8 rsvd;
u8 status;
};
struct cpl_set_tcb {
union opcode_tid ot;
u16 len;
u16 rsvd;
};
struct cpl_set_tcb_field {
union opcode_tid ot;
u8 rsvd[3];
u8 offset;
u32 mask;
u32 val;
};
struct cpl_set_tcb_rpl {
union opcode_tid ot;
u8 rsvd[3];
u8 status;
};
struct cpl_pcmd {
union opcode_tid ot;
u16 dlen_in;
u16 dlen_out;
u32 pcmd_parm[2];
};
struct cpl_pcmd_read {
union opcode_tid ot;
u32 rsvd1;
u16 rsvd2;
u32 addr;
u16 len;
};
struct cpl_pcmd_read_rpl {
union opcode_tid ot;
u16 len;
};
struct cpl_close_con_req {
union opcode_tid ot;
u32 rsvd;
};
struct cpl_close_con_rpl {
union opcode_tid ot;
u8 rsvd[3];
u8 status;
u32 snd_nxt;
u32 rcv_nxt;
};
struct cpl_close_listserv_req {
union opcode_tid ot;
u32 rsvd;
};
struct cpl_close_listserv_rpl {
union opcode_tid ot;
u8 rsvd[3];
u8 status;
};
struct cpl_abort_req {
union opcode_tid ot;
u32 rsvd0; u32 rsvd0;
u8 rsvd1;
u8 cmd;
u8 rsvd2[6];
};
struct cpl_abort_rpl {
union opcode_tid ot;
u32 rsvd0;
u8 rsvd1;
u8 status;
u8 rsvd2[6];
};
struct cpl_peer_close {
union opcode_tid ot;
u32 rsvd;
};
struct cpl_tx_data {
union opcode_tid ot;
u32 len;
u32 rsvd0;
u16 urg;
u16 flags;
};
struct cpl_tx_data_ack {
union opcode_tid ot;
u32 ack_seq;
};
struct cpl_rx_data {
union opcode_tid ot;
u32 len; u32 len;
u32 seq; u32 seq;
u16 urg; u16 urg;
u8 rsvd1; u8 rsvd;
u8 status;
};
struct cpl_rx_data_ack {
union opcode_tid ot;
u32 credit;
};
struct cpl_rx_data_ddp {
union opcode_tid ot;
u32 len;
u32 seq;
u32 nxt_seq;
u32 ulp_crc;
u16 ddp_status;
u8 rsvd;
u8 status; u8 status;
}; };
...@@ -99,9 +460,9 @@ struct cpl_tx_pkt_lso { ...@@ -99,9 +460,9 @@ struct cpl_tx_pkt_lso {
u8 ip_csum_dis:1; u8 ip_csum_dis:1;
u8 l4_csum_dis:1; u8 l4_csum_dis:1;
u8 vlan_valid:1; u8 vlan_valid:1;
u8 rsvd:1; u8 :1;
#else #else
u8 rsvd:1; u8 :1;
u8 vlan_valid:1; u8 vlan_valid:1;
u8 l4_csum_dis:1; u8 l4_csum_dis:1;
u8 ip_csum_dis:1; u8 ip_csum_dis:1;
...@@ -110,8 +471,7 @@ struct cpl_tx_pkt_lso { ...@@ -110,8 +471,7 @@ struct cpl_tx_pkt_lso {
u16 vlan; u16 vlan;
__be32 len; __be32 len;
u32 rsvd2; u8 rsvd[5];
u8 rsvd3;
#if defined(__LITTLE_ENDIAN_BITFIELD) #if defined(__LITTLE_ENDIAN_BITFIELD)
u8 tcp_hdr_words:4; u8 tcp_hdr_words:4;
u8 ip_hdr_words:4; u8 ip_hdr_words:4;
...@@ -138,8 +498,142 @@ struct cpl_rx_pkt { ...@@ -138,8 +498,142 @@ struct cpl_rx_pkt {
u8 iff:4; u8 iff:4;
#endif #endif
u16 csum; u16 csum;
__be16 vlan; u16 vlan;
u16 len; u16 len;
}; };
struct cpl_l2t_write_req {
union opcode_tid ot;
u32 params;
u8 rsvd1[2];
u8 dst_mac[6];
};
struct cpl_l2t_write_rpl {
union opcode_tid ot;
u8 status;
u8 rsvd[3];
};
struct cpl_l2t_read_req {
union opcode_tid ot;
u8 rsvd[3];
u8 l2t_idx;
};
struct cpl_l2t_read_rpl {
union opcode_tid ot;
u32 params;
u8 rsvd1[2];
u8 dst_mac[6];
};
struct cpl_smt_write_req {
union opcode_tid ot;
u8 rsvd0;
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 rsvd1:1;
u8 mtu_idx:3;
u8 iff:4;
#else
u8 iff:4;
u8 mtu_idx:3;
u8 rsvd1:1;
#endif
u16 rsvd2;
u16 rsvd3;
u8 src_mac1[6];
u16 rsvd4;
u8 src_mac0[6];
};
struct cpl_smt_write_rpl {
union opcode_tid ot;
u8 status;
u8 rsvd[3];
};
struct cpl_smt_read_req {
union opcode_tid ot;
u8 rsvd0;
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 rsvd1:4;
u8 iff:4;
#else
u8 iff:4;
u8 rsvd1:4;
#endif
u16 rsvd2;
};
struct cpl_smt_read_rpl {
union opcode_tid ot;
u8 status;
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 rsvd1:1;
u8 mtu_idx:3;
u8 rsvd0:4;
#else
u8 rsvd0:4;
u8 mtu_idx:3;
u8 rsvd1:1;
#endif
u16 rsvd2;
u16 rsvd3;
u8 src_mac1[6];
u16 rsvd4;
u8 src_mac0[6];
};
struct cpl_rte_delete_req {
union opcode_tid ot;
u32 params;
};
struct cpl_rte_delete_rpl {
union opcode_tid ot;
u8 status;
u8 rsvd[3];
};
struct cpl_rte_write_req {
union opcode_tid ot;
u32 params;
u32 netmask;
u32 faddr;
};
struct cpl_rte_write_rpl {
union opcode_tid ot;
u8 status;
u8 rsvd[3];
};
struct cpl_rte_read_req {
union opcode_tid ot;
u32 params;
};
struct cpl_rte_read_rpl {
union opcode_tid ot;
u8 status;
u8 rsvd0[2];
u8 l2t_idx;
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 rsvd1:7;
u8 select:1;
#else
u8 select:1;
u8 rsvd1:7;
#endif
u8 rsvd2[3];
u32 addr;
};
struct cpl_mss_change {
union opcode_tid ot;
u32 mss;
};
#endif /* _CXGB_CPL5_CMD_H_ */ #endif /* _CXGB_CPL5_CMD_H_ */
...@@ -53,7 +53,9 @@ ...@@ -53,7 +53,9 @@
#include "gmac.h" #include "gmac.h"
#include "cphy.h" #include "cphy.h"
#include "sge.h" #include "sge.h"
#include "tp.h"
#include "espi.h" #include "espi.h"
#include "elmer0.h"
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -73,10 +75,9 @@ static inline void cancel_mac_stats_update(struct adapter *ap) ...@@ -73,10 +75,9 @@ static inline void cancel_mac_stats_update(struct adapter *ap)
#define MAX_RX_JUMBO_BUFFERS 16384 #define MAX_RX_JUMBO_BUFFERS 16384
#define MAX_TX_BUFFERS_HIGH 16384U #define MAX_TX_BUFFERS_HIGH 16384U
#define MAX_TX_BUFFERS_LOW 1536U #define MAX_TX_BUFFERS_LOW 1536U
#define MAX_TX_BUFFERS 1460U
#define MIN_FL_ENTRIES 32 #define MIN_FL_ENTRIES 32
#define PORT_MASK ((1 << MAX_NPORTS) - 1)
#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
...@@ -94,8 +95,17 @@ MODULE_LICENSE("GPL"); ...@@ -94,8 +95,17 @@ MODULE_LICENSE("GPL");
static int dflt_msg_enable = DFLT_MSG_ENABLE; static int dflt_msg_enable = DFLT_MSG_ENABLE;
module_param(dflt_msg_enable, int, 0); module_param(dflt_msg_enable, int, 0);
MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap"); MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 default message enable bitmap");
#define HCLOCK 0x0
#define LCLOCK 0x1
/* T1 cards powersave mode */
static int t1_clock(struct adapter *adapter, int mode);
static int t1powersave = 1; /* HW default is powersave mode. */
module_param(t1powersave, int, 0);
MODULE_PARM_DESC(t1powersave, "Enable/Disable T1 powersaving mode");
static const char pci_speed[][4] = { static const char pci_speed[][4] = {
"33", "66", "100", "133" "33", "66", "100", "133"
...@@ -135,7 +145,7 @@ static void link_report(struct port_info *p) ...@@ -135,7 +145,7 @@ static void link_report(struct port_info *p)
} }
} }
void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, void t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat,
int speed, int duplex, int pause) int speed, int duplex, int pause)
{ {
struct port_info *p = &adapter->port[port_id]; struct port_info *p = &adapter->port[port_id];
...@@ -147,6 +157,22 @@ void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, ...@@ -147,6 +157,22 @@ void t1_link_changed(struct adapter *adapter, int port_id, int link_stat,
netif_carrier_off(p->dev); netif_carrier_off(p->dev);
link_report(p); link_report(p);
/* multi-ports: inform toe */
if ((speed > 0) && (adapter->params.nports > 1)) {
unsigned int sched_speed = 10;
switch (speed) {
case SPEED_1000:
sched_speed = 1000;
break;
case SPEED_100:
sched_speed = 100;
break;
case SPEED_10:
sched_speed = 10;
break;
}
t1_sched_update_parms(adapter->sge, port_id, 0, sched_speed);
}
} }
} }
...@@ -165,8 +191,10 @@ static void link_start(struct port_info *p) ...@@ -165,8 +191,10 @@ static void link_start(struct port_info *p)
static void enable_hw_csum(struct adapter *adapter) static void enable_hw_csum(struct adapter *adapter)
{ {
if (adapter->flags & TSO_CAPABLE) if (adapter->flags & TSO_CAPABLE)
t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */ t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
t1_tp_set_tcp_checksum_offload(adapter, 1); if (adapter->flags & UDP_CSUM_CAPABLE)
t1_tp_set_udp_checksum_offload(adapter->tp, 1);
t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
} }
/* /*
...@@ -468,6 +496,18 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, ...@@ -468,6 +496,18 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = (u64)t->tx_reg_pkts; *data++ = (u64)t->tx_reg_pkts;
*data++ = (u64)t->tx_lso_pkts; *data++ = (u64)t->tx_lso_pkts;
*data++ = (u64)t->tx_do_cksum; *data++ = (u64)t->tx_do_cksum;
if (adapter->espi) {
const struct espi_intr_counts *e;
e = t1_espi_get_intr_counts(adapter->espi);
*data++ = (u64) e->DIP2_parity_err;
*data++ = (u64) e->DIP4_err;
*data++ = (u64) e->rx_drops;
*data++ = (u64) e->tx_drops;
*data++ = (u64) e->rx_ovflw;
*data++ = (u64) e->parity_err;
}
} }
static inline void reg_block_dump(struct adapter *ap, void *buf, static inline void reg_block_dump(struct adapter *ap, void *buf,
...@@ -491,6 +531,15 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, ...@@ -491,6 +531,15 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
memset(buf, 0, T2_REGMAP_SIZE); memset(buf, 0, T2_REGMAP_SIZE);
reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
} }
static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
...@@ -729,7 +778,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) ...@@ -729,7 +778,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
static int get_eeprom_len(struct net_device *dev) static int get_eeprom_len(struct net_device *dev)
{ {
return EEPROM_SIZE; struct adapter *adapter = dev->priv;
return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
} }
#define EEPROM_MAGIC(ap) \ #define EEPROM_MAGIC(ap) \
...@@ -914,7 +965,7 @@ static void ext_intr_task(void *data) ...@@ -914,7 +965,7 @@ static void ext_intr_task(void *data)
{ {
struct adapter *adapter = data; struct adapter *adapter = data;
elmer0_ext_intr_handler(adapter); t1_elmer0_ext_intr_handler(adapter);
/* Now reenable external interrupts */ /* Now reenable external interrupts */
spin_lock_irq(&adapter->async_lock); spin_lock_irq(&adapter->async_lock);
...@@ -1074,16 +1125,19 @@ static int __devinit init_one(struct pci_dev *pdev, ...@@ -1074,16 +1125,19 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->vlan_rx_register = vlan_rx_register; netdev->vlan_rx_register = vlan_rx_register;
netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
#endif #endif
adapter->flags |= TSO_CAPABLE;
netdev->features |= NETIF_F_TSO; /* T204: disable TSO */
if (!(is_T2(adapter)) || bi->port_number != 4) {
adapter->flags |= TSO_CAPABLE;
netdev->features |= NETIF_F_TSO;
}
} }
netdev->open = cxgb_open; netdev->open = cxgb_open;
netdev->stop = cxgb_close; netdev->stop = cxgb_close;
netdev->hard_start_xmit = t1_start_xmit; netdev->hard_start_xmit = t1_start_xmit;
netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
sizeof(struct cpl_tx_pkt);
netdev->get_stats = t1_get_stats; netdev->get_stats = t1_get_stats;
netdev->set_multicast_list = t1_set_rxmode; netdev->set_multicast_list = t1_set_rxmode;
netdev->do_ioctl = t1_ioctl; netdev->do_ioctl = t1_ioctl;
...@@ -1134,6 +1188,17 @@ static int __devinit init_one(struct pci_dev *pdev, ...@@ -1134,6 +1188,17 @@ static int __devinit init_one(struct pci_dev *pdev,
bi->desc, adapter->params.chip_revision, bi->desc, adapter->params.chip_revision,
adapter->params.pci.is_pcix ? "PCIX" : "PCI", adapter->params.pci.is_pcix ? "PCIX" : "PCI",
adapter->params.pci.speed, adapter->params.pci.width); adapter->params.pci.speed, adapter->params.pci.width);
/*
* Set the T1B ASIC and memory clocks.
*/
if (t1powersave)
adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
else
adapter->t1powersave = HCLOCK;
if (t1_is_T1B(adapter))
t1_clock(adapter, t1powersave);
return 0; return 0;
out_release_adapter_res: out_release_adapter_res:
...@@ -1153,6 +1218,155 @@ static int __devinit init_one(struct pci_dev *pdev, ...@@ -1153,6 +1218,155 @@ static int __devinit init_one(struct pci_dev *pdev,
return err; return err;
} }
static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
{
int data;
int i;
u32 val;
enum {
S_CLOCK = 1 << 3,
S_DATA = 1 << 4
};
for (i = (nbits - 1); i > -1; i--) {
udelay(50);
data = ((bitdata >> i) & 0x1);
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
if (data)
val |= S_DATA;
else
val &= ~S_DATA;
udelay(50);
/* Set SCLOCK low */
val &= ~S_CLOCK;
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
/* Write SCLOCK high */
val |= S_CLOCK;
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
}
}
static int t1_clock(struct adapter *adapter, int mode)
{
u32 val;
int M_CORE_VAL;
int M_MEM_VAL;
enum {
M_CORE_BITS = 9,
T_CORE_VAL = 0,
T_CORE_BITS = 2,
N_CORE_VAL = 0,
N_CORE_BITS = 2,
M_MEM_BITS = 9,
T_MEM_VAL = 0,
T_MEM_BITS = 2,
N_MEM_VAL = 0,
N_MEM_BITS = 2,
NP_LOAD = 1 << 17,
S_LOAD_MEM = 1 << 5,
S_LOAD_CORE = 1 << 6,
S_CLOCK = 1 << 3
};
if (!t1_is_T1B(adapter))
return -ENODEV; /* Can't re-clock this chip. */
if (mode & 2) {
return 0; /* show current mode. */
}
if ((adapter->t1powersave & 1) == (mode & 1))
return -EALREADY; /* ASIC already running in mode. */
if ((mode & 1) == HCLOCK) {
M_CORE_VAL = 0x14;
M_MEM_VAL = 0x18;
adapter->t1powersave = HCLOCK; /* overclock */
} else {
M_CORE_VAL = 0xe;
M_MEM_VAL = 0x10;
adapter->t1powersave = LCLOCK; /* underclock */
}
/* Don't interrupt this serial stream! */
spin_lock(&adapter->tpi_lock);
/* Initialize for ASIC core */
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val |= NP_LOAD;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val &= ~S_LOAD_CORE;
val &= ~S_CLOCK;
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
/* Serial program the ASIC clock synthesizer */
bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
udelay(50);
/* Finish ASIC core */
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val |= S_LOAD_CORE;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val &= ~S_LOAD_CORE;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
/* Initialize for memory */
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val |= NP_LOAD;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val &= ~S_LOAD_MEM;
val &= ~S_CLOCK;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
/* Serial program the memory clock synthesizer */
bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
udelay(50);
/* Finish memory */
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val |= S_LOAD_MEM;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(50);
__t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val &= ~S_LOAD_MEM;
udelay(50);
__t1_tpi_write(adapter, A_ELMER0_GPO, val);
spin_unlock(&adapter->tpi_lock);
return 0;
}
static inline void t1_sw_reset(struct pci_dev *pdev) static inline void t1_sw_reset(struct pci_dev *pdev)
{ {
pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
......
...@@ -39,6 +39,12 @@ ...@@ -39,6 +39,12 @@
#ifndef _CXGB_ELMER0_H_ #ifndef _CXGB_ELMER0_H_
#define _CXGB_ELMER0_H_ #define _CXGB_ELMER0_H_
/* ELMER0 flavors */
enum {
ELMER0_XC2S300E_6FT256_C,
ELMER0_XC2S100E_6TQ144_C
};
/* ELMER0 registers */ /* ELMER0 registers */
#define A_ELMER0_VERSION 0x100000 #define A_ELMER0_VERSION 0x100000
#define A_ELMER0_PHY_CFG 0x100004 #define A_ELMER0_PHY_CFG 0x100004
...@@ -149,3 +155,4 @@ ...@@ -149,3 +155,4 @@
#define MI1_OP_INDIRECT_READ 3 #define MI1_OP_INDIRECT_READ 3
#endif /* _CXGB_ELMER0_H_ */ #endif /* _CXGB_ELMER0_H_ */
...@@ -81,46 +81,36 @@ static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr, ...@@ -81,46 +81,36 @@ static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr,
return busy; return busy;
} }
/* 1. Deassert rx_reset_core. */
/* 2. Program TRICN_CNFG registers. */
/* 3. Deassert rx_reset_link */
static int tricn_init(adapter_t *adapter) static int tricn_init(adapter_t *adapter)
{ {
int i = 0; int i, sme = 1;
int stat = 0;
int timeout = 0;
int is_ready = 0;
/* 1 */ if (!(readl(adapter->regs + A_ESPI_RX_RESET) & F_RX_CLK_STATUS)) {
timeout=1000; CH_ERR("%s: ESPI clock not ready\n", adapter->name);
do { return -1;
stat = readl(adapter->regs + A_ESPI_RX_RESET);
is_ready = (stat & 0x4);
timeout--;
udelay(5);
} while (!is_ready || (timeout==0));
writel(0x2, adapter->regs + A_ESPI_RX_RESET);
if (timeout==0)
{
CH_ERR("ESPI : ERROR : Timeout tricn_init() \n");
t1_fatal_err(adapter);
} }
/* 2 */ writel(F_ESPI_RX_CORE_RST, adapter->regs + A_ESPI_RX_RESET);
tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81);
tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81); if (sme) {
tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81); tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81);
for (i=1; i<= 8; i++) tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1); tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81);
for (i=1; i<= 2; i++) tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1); tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81);
for (i=1; i<= 3; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); }
for (i=4; i<= 4; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); for (i = 1; i <= 8; i++)
for (i=5; i<= 5; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1);
for (i=6; i<= 6; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); for (i = 1; i <= 2; i++)
for (i=7; i<= 7; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0x80); tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1);
for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); for (i = 1; i <= 3; i++)
tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1);
/* 3 */ tricn_write(adapter, 0, 2, 4, TRICN_CNFG, 0xf1);
writel(0x3, adapter->regs + A_ESPI_RX_RESET); tricn_write(adapter, 0, 2, 5, TRICN_CNFG, 0xe1);
tricn_write(adapter, 0, 2, 6, TRICN_CNFG, 0xf1);
tricn_write(adapter, 0, 2, 7, TRICN_CNFG, 0x80);
tricn_write(adapter, 0, 2, 8, TRICN_CNFG, 0xf1);
writel(F_ESPI_RX_CORE_RST | F_ESPI_RX_LNK_RST,
adapter->regs + A_ESPI_RX_RESET);
return 0; return 0;
} }
...@@ -143,6 +133,7 @@ void t1_espi_intr_enable(struct peespi *espi) ...@@ -143,6 +133,7 @@ void t1_espi_intr_enable(struct peespi *espi)
void t1_espi_intr_clear(struct peespi *espi) void t1_espi_intr_clear(struct peespi *espi)
{ {
readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS); writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS);
writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE); writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE);
} }
...@@ -157,7 +148,6 @@ void t1_espi_intr_disable(struct peespi *espi) ...@@ -157,7 +148,6 @@ void t1_espi_intr_disable(struct peespi *espi)
int t1_espi_intr_handler(struct peespi *espi) int t1_espi_intr_handler(struct peespi *espi)
{ {
u32 cnt;
u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS); u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
if (status & F_DIP4ERR) if (status & F_DIP4ERR)
...@@ -177,7 +167,7 @@ int t1_espi_intr_handler(struct peespi *espi) ...@@ -177,7 +167,7 @@ int t1_espi_intr_handler(struct peespi *espi)
* Must read the error count to clear the interrupt * Must read the error count to clear the interrupt
* that it causes. * that it causes.
*/ */
cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT); readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
} }
/* /*
...@@ -210,17 +200,45 @@ static void espi_setup_for_pm3393(adapter_t *adapter) ...@@ -210,17 +200,45 @@ static void espi_setup_for_pm3393(adapter_t *adapter)
writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG); writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG);
} }
/* T2 Init part -- */ static void espi_setup_for_vsc7321(adapter_t *adapter)
/* 1. Set T_ESPI_MISCCTRL_ADDR */ {
/* 2. Init ESPI registers. */ writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0);
/* 3. Init TriCN Hard Macro */ writel(0x1f401f4, adapter->regs + A_ESPI_SCH_TOKEN1);
int t1_espi_init(struct peespi *espi, int mac_type, int nports) writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2);
writel(0xa00, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
writel(0x1ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
writel(1, adapter->regs + A_ESPI_CALENDAR_LENGTH);
writel(V_RX_NPORTS(4) | V_TX_NPORTS(4), adapter->regs + A_PORT_CONFIG);
writel(0x08000008, adapter->regs + A_ESPI_TRAIN);
}
/*
* 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)
{ {
u32 cnt; writel(1, adapter->regs + A_ESPI_CALENDAR_LENGTH);
if (nports == 4) {
if (is_T2(adapter)) {
writel(0xf00, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
writel(0x3c0, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
} else {
writel(0x7ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
writel(0x1ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
}
} else {
writel(0x1fff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
writel(0x7ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
}
writel(V_RX_NPORTS(nports) | V_TX_NPORTS(nports), adapter->regs + A_PORT_CONFIG);
}
int t1_espi_init(struct peespi *espi, int mac_type, int nports)
{
u32 status_enable_extra = 0; u32 status_enable_extra = 0;
adapter_t *adapter = espi->adapter; adapter_t *adapter = espi->adapter;
u32 status, burstval = 0x800100;
/* Disable ESPI training. MACs that can handle it enable it below. */ /* Disable ESPI training. MACs that can handle it enable it below. */
writel(0, adapter->regs + A_ESPI_TRAIN); writel(0, adapter->regs + A_ESPI_TRAIN);
...@@ -229,38 +247,20 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports) ...@@ -229,38 +247,20 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
writel(V_OUT_OF_SYNC_COUNT(4) | writel(V_OUT_OF_SYNC_COUNT(4) |
V_DIP2_PARITY_ERR_THRES(3) | V_DIP2_PARITY_ERR_THRES(3) |
V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL); V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL);
if (nports == 4) { writel(nports == 4 ? 0x200040 : 0x1000080,
/* T204: maxburst1 = 0x40, maxburst2 = 0x20 */ adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
burstval = 0x200040; } else
} writel(0x800100, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
}
writel(burstval, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
switch (mac_type) { if (mac_type == CHBT_MAC_PM3393)
case CHBT_MAC_PM3393:
espi_setup_for_pm3393(adapter); espi_setup_for_pm3393(adapter);
break; else if (mac_type == CHBT_MAC_VSC7321)
default: espi_setup_for_vsc7321(adapter);
else if (mac_type == CHBT_MAC_IXF1010) {
status_enable_extra = F_INTEL1010MODE;
espi_setup_for_ixf1010(adapter, nports);
} else
return -1; return -1;
}
/*
* Make sure any pending interrupts from the SPI are
* Cleared before enabling the interrupt.
*/
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 = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
}
/*
* For T1B we need to write 1 to clear ESPI interrupts. For T2+ we
* write the status as is.
*/
if (status && t1_is_T1B(espi->adapter))
status = 1;
writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
writel(status_enable_extra | F_RXSTATUSENABLE, writel(status_enable_extra | F_RXSTATUSENABLE,
adapter->regs + A_ESPI_FIFO_STATUS_ENABLE); adapter->regs + A_ESPI_FIFO_STATUS_ENABLE);
...@@ -271,9 +271,11 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports) ...@@ -271,9 +271,11 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
* Always position the control at the 1st port egress IN * Always position the control at the 1st port egress IN
* (sop,eop) counter to reduce PIOs for T/N210 workaround. * (sop,eop) counter to reduce PIOs for T/N210 workaround.
*/ */
espi->misc_ctrl = (readl(adapter->regs + A_ESPI_MISC_CONTROL) espi->misc_ctrl = readl(adapter->regs + A_ESPI_MISC_CONTROL);
& ~MON_MASK) | (F_MONITORED_DIRECTION espi->misc_ctrl &= ~MON_MASK;
| F_MONITORED_INTERFACE); espi->misc_ctrl |= F_MONITORED_DIRECTION;
if (adapter->params.nports == 1)
espi->misc_ctrl |= F_MONITORED_INTERFACE;
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
spin_lock_init(&espi->lock); spin_lock_init(&espi->lock);
} }
...@@ -299,8 +301,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) ...@@ -299,8 +301,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
{ {
struct peespi *espi = adapter->espi; struct peespi *espi = adapter->espi;
if (!is_T2(adapter)) if (!is_T2(adapter)) return;
return;
spin_lock(&espi->lock); spin_lock(&espi->lock);
espi->misc_ctrl = (val & ~MON_MASK) | espi->misc_ctrl = (val & ~MON_MASK) |
(espi->misc_ctrl & MON_MASK); (espi->misc_ctrl & MON_MASK);
...@@ -310,27 +311,61 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) ...@@ -310,27 +311,61 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
{ {
u32 sel;
struct peespi *espi = adapter->espi; struct peespi *espi = adapter->espi;
u32 sel;
if (!is_T2(adapter)) if (!is_T2(adapter))
return 0; return 0;
sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2); sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2);
if (!wait) { if (!wait) {
if (!spin_trylock(&espi->lock)) if (!spin_trylock(&espi->lock))
return 0; return 0;
} } else
else
spin_lock(&espi->lock); spin_lock(&espi->lock);
if ((sel != (espi->misc_ctrl & MON_MASK))) { if ((sel != (espi->misc_ctrl & MON_MASK))) {
writel(((espi->misc_ctrl & ~MON_MASK) | sel), writel(((espi->misc_ctrl & ~MON_MASK) | sel),
adapter->regs + A_ESPI_MISC_CONTROL); adapter->regs + A_ESPI_MISC_CONTROL);
sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
} } else
else
sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
spin_unlock(&espi->lock); spin_unlock(&espi->lock);
return sel; return sel;
} }
/*
* This function is for T204 only.
* compare with t1_espi_get_mon(), it reads espiInTxSop[0 ~ 3] in
* one shot, since there is no per port counter on the out side.
*/
int
t1_espi_get_mon_t204(adapter_t *adapter, u32 *valp, u8 wait)
{
struct peespi *espi = adapter->espi;
u8 i, nport = (u8)adapter->params.nports;
if (!wait) {
if (!spin_trylock(&espi->lock))
return -1;
} else
spin_lock(&espi->lock);
if ( (espi->misc_ctrl & MON_MASK) != F_MONITORED_DIRECTION ) {
espi->misc_ctrl = (espi->misc_ctrl & ~MON_MASK) |
F_MONITORED_DIRECTION;
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
}
for (i = 0 ; i < nport; i++, valp++) {
if (i) {
writel(espi->misc_ctrl | V_MONITORED_PORT_NUM(i),
adapter->regs + A_ESPI_MISC_CONTROL);
}
*valp = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
}
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
spin_unlock(&espi->lock);
return 0;
}
...@@ -64,5 +64,6 @@ const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi); ...@@ -64,5 +64,6 @@ const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi);
void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val); void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val);
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait); u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait);
int t1_espi_get_mon_t204(adapter_t *, u32 *, u8);
#endif /* _CXGB_ESPI_H_ */ #endif /* _CXGB_ESPI_H_ */
/* $Date: 2005/03/07 23:59:05 $ $RCSfile: fpga_defs.h,v $ $Revision: 1.4 $ */
/*
* FPGA specific definitions
*/
#ifndef __CHELSIO_FPGA_DEFS_H__
#define __CHELSIO_FPGA_DEFS_H__
#define FPGA_PCIX_ADDR_VERSION 0xA08
#define FPGA_PCIX_ADDR_STAT 0xA0C
/* FPGA master interrupt Cause/Enable bits */
#define FPGA_PCIX_INTERRUPT_SGE_ERROR 0x1
#define FPGA_PCIX_INTERRUPT_SGE_DATA 0x2
#define FPGA_PCIX_INTERRUPT_TP 0x4
#define FPGA_PCIX_INTERRUPT_MC3 0x8
#define FPGA_PCIX_INTERRUPT_GMAC 0x10
#define FPGA_PCIX_INTERRUPT_PCIX 0x20
/* TP interrupt register addresses */
#define FPGA_TP_ADDR_INTERRUPT_ENABLE 0xA10
#define FPGA_TP_ADDR_INTERRUPT_CAUSE 0xA14
#define FPGA_TP_ADDR_VERSION 0xA18
/* TP interrupt Cause/Enable bits */
#define FPGA_TP_INTERRUPT_MC4 0x1
#define FPGA_TP_INTERRUPT_MC5 0x2
/*
* PM interrupt register addresses
*/
#define FPGA_MC3_REG_INTRENABLE 0xA20
#define FPGA_MC3_REG_INTRCAUSE 0xA24
#define FPGA_MC3_REG_VERSION 0xA28
/*
* GMAC interrupt register addresses
*/
#define FPGA_GMAC_ADDR_INTERRUPT_ENABLE 0xA30
#define FPGA_GMAC_ADDR_INTERRUPT_CAUSE 0xA34
#define FPGA_GMAC_ADDR_VERSION 0xA38
/* GMAC Cause/Enable bits */
#define FPGA_GMAC_INTERRUPT_PORT0 0x1
#define FPGA_GMAC_INTERRUPT_PORT1 0x2
#define FPGA_GMAC_INTERRUPT_PORT2 0x4
#define FPGA_GMAC_INTERRUPT_PORT3 0x8
/* MI0 registers */
#define A_MI0_CLK 0xb00
#define S_MI0_CLK_DIV 0
#define M_MI0_CLK_DIV 0xff
#define V_MI0_CLK_DIV(x) ((x) << S_MI0_CLK_DIV)
#define G_MI0_CLK_DIV(x) (((x) >> S_MI0_CLK_DIV) & M_MI0_CLK_DIV)
#define S_MI0_CLK_CNT 8
#define M_MI0_CLK_CNT 0xff
#define V_MI0_CLK_CNT(x) ((x) << S_MI0_CLK_CNT)
#define G_MI0_CLK_CNT(x) (((x) >> S_MI0_CLK_CNT) & M_MI0_CLK_CNT)
#define A_MI0_CSR 0xb04
#define S_MI0_CSR_POLL 0
#define V_MI0_CSR_POLL(x) ((x) << S_MI0_CSR_POLL)
#define F_MI0_CSR_POLL V_MI0_CSR_POLL(1U)
#define S_MI0_PREAMBLE 1
#define V_MI0_PREAMBLE(x) ((x) << S_MI0_PREAMBLE)
#define F_MI0_PREAMBLE V_MI0_PREAMBLE(1U)
#define S_MI0_INTR_ENABLE 2
#define V_MI0_INTR_ENABLE(x) ((x) << S_MI0_INTR_ENABLE)
#define F_MI0_INTR_ENABLE V_MI0_INTR_ENABLE(1U)
#define S_MI0_BUSY 3
#define V_MI0_BUSY(x) ((x) << S_MI0_BUSY)
#define F_MI0_BUSY V_MI0_BUSY(1U)
#define S_MI0_MDIO 4
#define V_MI0_MDIO(x) ((x) << S_MI0_MDIO)
#define F_MI0_MDIO V_MI0_MDIO(1U)
#define A_MI0_ADDR 0xb08
#define S_MI0_PHY_REG_ADDR 0
#define M_MI0_PHY_REG_ADDR 0x1f
#define V_MI0_PHY_REG_ADDR(x) ((x) << S_MI0_PHY_REG_ADDR)
#define G_MI0_PHY_REG_ADDR(x) (((x) >> S_MI0_PHY_REG_ADDR) & M_MI0_PHY_REG_ADDR)
#define S_MI0_PHY_ADDR 5
#define M_MI0_PHY_ADDR 0x1f
#define V_MI0_PHY_ADDR(x) ((x) << S_MI0_PHY_ADDR)
#define G_MI0_PHY_ADDR(x) (((x) >> S_MI0_PHY_ADDR) & M_MI0_PHY_ADDR)
#define A_MI0_DATA_EXT 0xb0c
#define A_MI0_DATA_INT 0xb10
/* GMAC registers */
#define A_GMAC_MACID_LO 0x28
#define A_GMAC_MACID_HI 0x2c
#define A_GMAC_CSR 0x30
#define S_INTERFACE 0
#define M_INTERFACE 0x3
#define V_INTERFACE(x) ((x) << S_INTERFACE)
#define G_INTERFACE(x) (((x) >> S_INTERFACE) & M_INTERFACE)
#define S_MAC_TX_ENABLE 2
#define V_MAC_TX_ENABLE(x) ((x) << S_MAC_TX_ENABLE)
#define F_MAC_TX_ENABLE V_MAC_TX_ENABLE(1U)
#define S_MAC_RX_ENABLE 3
#define V_MAC_RX_ENABLE(x) ((x) << S_MAC_RX_ENABLE)
#define F_MAC_RX_ENABLE V_MAC_RX_ENABLE(1U)
#define S_MAC_LB_ENABLE 4
#define V_MAC_LB_ENABLE(x) ((x) << S_MAC_LB_ENABLE)
#define F_MAC_LB_ENABLE V_MAC_LB_ENABLE(1U)
#define S_MAC_SPEED 5
#define M_MAC_SPEED 0x3
#define V_MAC_SPEED(x) ((x) << S_MAC_SPEED)
#define G_MAC_SPEED(x) (((x) >> S_MAC_SPEED) & M_MAC_SPEED)
#define S_MAC_HD_FC_ENABLE 7
#define V_MAC_HD_FC_ENABLE(x) ((x) << S_MAC_HD_FC_ENABLE)
#define F_MAC_HD_FC_ENABLE V_MAC_HD_FC_ENABLE(1U)
#define S_MAC_HALF_DUPLEX 8
#define V_MAC_HALF_DUPLEX(x) ((x) << S_MAC_HALF_DUPLEX)
#define F_MAC_HALF_DUPLEX V_MAC_HALF_DUPLEX(1U)
#define S_MAC_PROMISC 9
#define V_MAC_PROMISC(x) ((x) << S_MAC_PROMISC)
#define F_MAC_PROMISC V_MAC_PROMISC(1U)
#define S_MAC_MC_ENABLE 10
#define V_MAC_MC_ENABLE(x) ((x) << S_MAC_MC_ENABLE)
#define F_MAC_MC_ENABLE V_MAC_MC_ENABLE(1U)
#define S_MAC_RESET 11
#define V_MAC_RESET(x) ((x) << S_MAC_RESET)
#define F_MAC_RESET V_MAC_RESET(1U)
#define S_MAC_RX_PAUSE_ENABLE 12
#define V_MAC_RX_PAUSE_ENABLE(x) ((x) << S_MAC_RX_PAUSE_ENABLE)
#define F_MAC_RX_PAUSE_ENABLE V_MAC_RX_PAUSE_ENABLE(1U)
#define S_MAC_TX_PAUSE_ENABLE 13
#define V_MAC_TX_PAUSE_ENABLE(x) ((x) << S_MAC_TX_PAUSE_ENABLE)
#define F_MAC_TX_PAUSE_ENABLE V_MAC_TX_PAUSE_ENABLE(1U)
#define S_MAC_LWM_ENABLE 14
#define V_MAC_LWM_ENABLE(x) ((x) << S_MAC_LWM_ENABLE)
#define F_MAC_LWM_ENABLE V_MAC_LWM_ENABLE(1U)
#define S_MAC_MAGIC_PKT_ENABLE 15
#define V_MAC_MAGIC_PKT_ENABLE(x) ((x) << S_MAC_MAGIC_PKT_ENABLE)
#define F_MAC_MAGIC_PKT_ENABLE V_MAC_MAGIC_PKT_ENABLE(1U)
#define S_MAC_ISL_ENABLE 16
#define V_MAC_ISL_ENABLE(x) ((x) << S_MAC_ISL_ENABLE)
#define F_MAC_ISL_ENABLE V_MAC_ISL_ENABLE(1U)
#define S_MAC_JUMBO_ENABLE 17
#define V_MAC_JUMBO_ENABLE(x) ((x) << S_MAC_JUMBO_ENABLE)
#define F_MAC_JUMBO_ENABLE V_MAC_JUMBO_ENABLE(1U)
#define S_MAC_RX_PAD_ENABLE 18
#define V_MAC_RX_PAD_ENABLE(x) ((x) << S_MAC_RX_PAD_ENABLE)
#define F_MAC_RX_PAD_ENABLE V_MAC_RX_PAD_ENABLE(1U)
#define S_MAC_RX_CRC_ENABLE 19
#define V_MAC_RX_CRC_ENABLE(x) ((x) << S_MAC_RX_CRC_ENABLE)
#define F_MAC_RX_CRC_ENABLE V_MAC_RX_CRC_ENABLE(1U)
#define A_GMAC_IFS 0x34
#define S_MAC_IFS2 0
#define M_MAC_IFS2 0x3f
#define V_MAC_IFS2(x) ((x) << S_MAC_IFS2)
#define G_MAC_IFS2(x) (((x) >> S_MAC_IFS2) & M_MAC_IFS2)
#define S_MAC_IFS1 8
#define M_MAC_IFS1 0x7f
#define V_MAC_IFS1(x) ((x) << S_MAC_IFS1)
#define G_MAC_IFS1(x) (((x) >> S_MAC_IFS1) & M_MAC_IFS1)
#define A_GMAC_JUMBO_FRAME_LEN 0x38
#define A_GMAC_LNK_DLY 0x3c
#define A_GMAC_PAUSETIME 0x40
#define A_GMAC_MCAST_LO 0x44
#define A_GMAC_MCAST_HI 0x48
#define A_GMAC_MCAST_MASK_LO 0x4c
#define A_GMAC_MCAST_MASK_HI 0x50
#define A_GMAC_RMT_CNT 0x54
#define A_GMAC_RMT_DATA 0x58
#define A_GMAC_BACKOFF_SEED 0x5c
#define A_GMAC_TXF_THRES 0x60
#define S_TXF_READ_THRESHOLD 0
#define M_TXF_READ_THRESHOLD 0xff
#define V_TXF_READ_THRESHOLD(x) ((x) << S_TXF_READ_THRESHOLD)
#define G_TXF_READ_THRESHOLD(x) (((x) >> S_TXF_READ_THRESHOLD) & M_TXF_READ_THRESHOLD)
#define S_TXF_WRITE_THRESHOLD 16
#define M_TXF_WRITE_THRESHOLD 0xff
#define V_TXF_WRITE_THRESHOLD(x) ((x) << S_TXF_WRITE_THRESHOLD)
#define G_TXF_WRITE_THRESHOLD(x) (((x) >> S_TXF_WRITE_THRESHOLD) & M_TXF_WRITE_THRESHOLD)
#define MAC_REG_BASE 0x600
#define MAC_REG_ADDR(idx, reg) (MAC_REG_BASE + (idx) * 128 + (reg))
#define MAC_REG_IDLO(idx) MAC_REG_ADDR(idx, A_GMAC_MACID_LO)
#define MAC_REG_IDHI(idx) MAC_REG_ADDR(idx, A_GMAC_MACID_HI)
#define MAC_REG_CSR(idx) MAC_REG_ADDR(idx, A_GMAC_CSR)
#define MAC_REG_IFS(idx) MAC_REG_ADDR(idx, A_GMAC_IFS)
#define MAC_REG_LARGEFRAMELENGTH(idx) MAC_REG_ADDR(idx, A_GMAC_JUMBO_FRAME_LEN)
#define MAC_REG_LINKDLY(idx) MAC_REG_ADDR(idx, A_GMAC_LNK_DLY)
#define MAC_REG_PAUSETIME(idx) MAC_REG_ADDR(idx, A_GMAC_PAUSETIME)
#define MAC_REG_CASTLO(idx) MAC_REG_ADDR(idx, A_GMAC_MCAST_LO)
#define MAC_REG_MCASTHI(idx) MAC_REG_ADDR(idx, A_GMAC_MCAST_HI)
#define MAC_REG_CASTMASKLO(idx) MAC_REG_ADDR(idx, A_GMAC_MCAST_MASK_LO)
#define MAC_REG_MCASTMASKHI(idx) MAC_REG_ADDR(idx, A_GMAC_MCAST_MASK_HI)
#define MAC_REG_RMCNT(idx) MAC_REG_ADDR(idx, A_GMAC_RMT_CNT)
#define MAC_REG_RMDATA(idx) MAC_REG_ADDR(idx, A_GMAC_RMT_DATA)
#define MAC_REG_GMRANDBACKOFFSEED(idx) MAC_REG_ADDR(idx, A_GMAC_BACKOFF_SEED)
#define MAC_REG_TXFTHRESHOLDS(idx) MAC_REG_ADDR(idx, A_GMAC_TXF_THRES)
#endif
...@@ -62,6 +62,8 @@ struct cmac_statistics { ...@@ -62,6 +62,8 @@ struct cmac_statistics {
u64 TxInternalMACXmitError; u64 TxInternalMACXmitError;
u64 TxFramesWithExcessiveDeferral; u64 TxFramesWithExcessiveDeferral;
u64 TxFCSErrors; u64 TxFCSErrors;
u64 TxJumboFramesOK;
u64 TxJumboOctetsOK;
/* Receive */ /* Receive */
u64 RxOctetsOK; u64 RxOctetsOK;
...@@ -81,6 +83,8 @@ struct cmac_statistics { ...@@ -81,6 +83,8 @@ struct cmac_statistics {
u64 RxInRangeLengthErrors; u64 RxInRangeLengthErrors;
u64 RxOutOfRangeLengthField; u64 RxOutOfRangeLengthField;
u64 RxFrameTooLongErrors; u64 RxFrameTooLongErrors;
u64 RxJumboFramesOK;
u64 RxJumboOctetsOK;
}; };
struct cmac_ops { struct cmac_ops {
...@@ -128,6 +132,7 @@ struct gmac { ...@@ -128,6 +132,7 @@ struct gmac {
extern struct gmac t1_pm3393_ops; extern struct gmac t1_pm3393_ops;
extern struct gmac t1_chelsio_mac_ops; extern struct gmac t1_chelsio_mac_ops;
extern struct gmac t1_vsc7321_ops; extern struct gmac t1_vsc7321_ops;
extern struct gmac t1_vsc7326_ops;
extern struct gmac t1_ixf1010_ops; extern struct gmac t1_ixf1010_ops;
extern struct gmac t1_dummy_mac_ops; extern struct gmac t1_dummy_mac_ops;
......
/* $Date: 2005/03/07 23:59:05 $ $RCSfile: mv88e1xxx.h,v $ $Revision: 1.13 $ */
#ifndef CHELSIO_MV8E1XXX_H
#define CHELSIO_MV8E1XXX_H
#ifndef BMCR_SPEED1000
# define BMCR_SPEED1000 0x40
#endif
#ifndef ADVERTISE_PAUSE
# define ADVERTISE_PAUSE 0x400
#endif
#ifndef ADVERTISE_PAUSE_ASYM
# define ADVERTISE_PAUSE_ASYM 0x800
#endif
/* Gigabit MII registers */
#define MII_GBCR 9 /* 1000Base-T control register */
#define MII_GBSR 10 /* 1000Base-T status register */
/* 1000Base-T control register fields */
#define GBCR_ADV_1000HALF 0x100
#define GBCR_ADV_1000FULL 0x200
#define GBCR_PREFER_MASTER 0x400
#define GBCR_MANUAL_AS_MASTER 0x800
#define GBCR_MANUAL_CONFIG_ENABLE 0x1000
/* 1000Base-T status register fields */
#define GBSR_LP_1000HALF 0x400
#define GBSR_LP_1000FULL 0x800
#define GBSR_REMOTE_OK 0x1000
#define GBSR_LOCAL_OK 0x2000
#define GBSR_LOCAL_MASTER 0x4000
#define GBSR_MASTER_FAULT 0x8000
/* Marvell PHY interrupt status bits. */
#define MV88E1XXX_INTR_JABBER 0x0001
#define MV88E1XXX_INTR_POLARITY_CHNG 0x0002
#define MV88E1XXX_INTR_ENG_DETECT_CHNG 0x0010
#define MV88E1XXX_INTR_DOWNSHIFT 0x0020
#define MV88E1XXX_INTR_MDI_XOVER_CHNG 0x0040
#define MV88E1XXX_INTR_FIFO_OVER_UNDER 0x0080
#define MV88E1XXX_INTR_FALSE_CARRIER 0x0100
#define MV88E1XXX_INTR_SYMBOL_ERROR 0x0200
#define MV88E1XXX_INTR_LINK_CHNG 0x0400
#define MV88E1XXX_INTR_AUTONEG_DONE 0x0800
#define MV88E1XXX_INTR_PAGE_RECV 0x1000
#define MV88E1XXX_INTR_DUPLEX_CHNG 0x2000
#define MV88E1XXX_INTR_SPEED_CHNG 0x4000
#define MV88E1XXX_INTR_AUTONEG_ERR 0x8000
/* Marvell PHY specific registers. */
#define MV88E1XXX_SPECIFIC_CNTRL_REGISTER 16
#define MV88E1XXX_SPECIFIC_STATUS_REGISTER 17
#define MV88E1XXX_INTERRUPT_ENABLE_REGISTER 18
#define MV88E1XXX_INTERRUPT_STATUS_REGISTER 19
#define MV88E1XXX_EXT_PHY_SPECIFIC_CNTRL_REGISTER 20
#define MV88E1XXX_RECV_ERR_CNTR_REGISTER 21
#define MV88E1XXX_RES_REGISTER 22
#define MV88E1XXX_GLOBAL_STATUS_REGISTER 23
#define MV88E1XXX_LED_CONTROL_REGISTER 24
#define MV88E1XXX_MANUAL_LED_OVERRIDE_REGISTER 25
#define MV88E1XXX_EXT_PHY_SPECIFIC_CNTRL_2_REGISTER 26
#define MV88E1XXX_EXT_PHY_SPECIFIC_STATUS_REGISTER 27
#define MV88E1XXX_VIRTUAL_CABLE_TESTER_REGISTER 28
#define MV88E1XXX_EXTENDED_ADDR_REGISTER 29
#define MV88E1XXX_EXTENDED_REGISTER 30
/* PHY specific control register fields */
#define S_PSCR_MDI_XOVER_MODE 5
#define M_PSCR_MDI_XOVER_MODE 0x3
#define V_PSCR_MDI_XOVER_MODE(x) ((x) << S_PSCR_MDI_XOVER_MODE)
#define G_PSCR_MDI_XOVER_MODE(x) (((x) >> S_PSCR_MDI_XOVER_MODE) & M_PSCR_MDI_XOVER_MODE)
/* Extended PHY specific control register fields */
#define S_DOWNSHIFT_ENABLE 8
#define V_DOWNSHIFT_ENABLE (1 << S_DOWNSHIFT_ENABLE)
#define S_DOWNSHIFT_CNT 9
#define M_DOWNSHIFT_CNT 0x7
#define V_DOWNSHIFT_CNT(x) ((x) << S_DOWNSHIFT_CNT)
#define G_DOWNSHIFT_CNT(x) (((x) >> S_DOWNSHIFT_CNT) & M_DOWNSHIFT_CNT)
/* PHY specific status register fields */
#define S_PSSR_JABBER 0
#define V_PSSR_JABBER (1 << S_PSSR_JABBER)
#define S_PSSR_POLARITY 1
#define V_PSSR_POLARITY (1 << S_PSSR_POLARITY)
#define S_PSSR_RX_PAUSE 2
#define V_PSSR_RX_PAUSE (1 << S_PSSR_RX_PAUSE)
#define S_PSSR_TX_PAUSE 3
#define V_PSSR_TX_PAUSE (1 << S_PSSR_TX_PAUSE)
#define S_PSSR_ENERGY_DETECT 4
#define V_PSSR_ENERGY_DETECT (1 << S_PSSR_ENERGY_DETECT)
#define S_PSSR_DOWNSHIFT_STATUS 5
#define V_PSSR_DOWNSHIFT_STATUS (1 << S_PSSR_DOWNSHIFT_STATUS)
#define S_PSSR_MDI 6
#define V_PSSR_MDI (1 << S_PSSR_MDI)
#define S_PSSR_CABLE_LEN 7
#define M_PSSR_CABLE_LEN 0x7
#define V_PSSR_CABLE_LEN(x) ((x) << S_PSSR_CABLE_LEN)
#define G_PSSR_CABLE_LEN(x) (((x) >> S_PSSR_CABLE_LEN) & M_PSSR_CABLE_LEN)
#define S_PSSR_LINK 10
#define V_PSSR_LINK (1 << S_PSSR_LINK)
#define S_PSSR_STATUS_RESOLVED 11
#define V_PSSR_STATUS_RESOLVED (1 << S_PSSR_STATUS_RESOLVED)
#define S_PSSR_PAGE_RECEIVED 12
#define V_PSSR_PAGE_RECEIVED (1 << S_PSSR_PAGE_RECEIVED)
#define S_PSSR_DUPLEX 13
#define V_PSSR_DUPLEX (1 << S_PSSR_DUPLEX)
#define S_PSSR_SPEED 14
#define M_PSSR_SPEED 0x3
#define V_PSSR_SPEED(x) ((x) << S_PSSR_SPEED)
#define G_PSSR_SPEED(x) (((x) >> S_PSSR_SPEED) & M_PSSR_SPEED)
#endif
...@@ -85,29 +85,33 @@ static int mv88x201x_reset(struct cphy *cphy, int wait) ...@@ -85,29 +85,33 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
static int mv88x201x_interrupt_enable(struct cphy *cphy) static int mv88x201x_interrupt_enable(struct cphy *cphy)
{ {
u32 elmer;
/* Enable PHY LASI interrupts. */ /* Enable PHY LASI interrupts. */
mdio_write(cphy, 0x1, 0x9002, 0x1); mdio_write(cphy, 0x1, 0x9002, 0x1);
/* Enable Marvell interrupts through Elmer0. */ /* Enable Marvell interrupts through Elmer0. */
t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); if (t1_is_asic(cphy->adapter)) {
elmer |= ELMER0_GP_BIT6; u32 elmer;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, 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; return 0;
} }
static int mv88x201x_interrupt_disable(struct cphy *cphy) static int mv88x201x_interrupt_disable(struct cphy *cphy)
{ {
u32 elmer;
/* Disable PHY LASI interrupts. */ /* Disable PHY LASI interrupts. */
mdio_write(cphy, 0x1, 0x9002, 0x0); mdio_write(cphy, 0x1, 0x9002, 0x0);
/* Disable Marvell interrupts through Elmer0. */ /* Disable Marvell interrupts through Elmer0. */
t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); if (t1_is_asic(cphy->adapter)) {
elmer &= ~ELMER0_GP_BIT6; u32 elmer;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, 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; return 0;
} }
...@@ -140,9 +144,11 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy) ...@@ -140,9 +144,11 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
#endif #endif
/* Clear Marvell interrupts through Elmer0. */ /* Clear Marvell interrupts through Elmer0. */
t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer); if (t1_is_asic(cphy->adapter)) {
elmer |= ELMER0_GP_BIT6; t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer); elmer |= ELMER0_GP_BIT6;
t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
}
return 0; return 0;
} }
......
/* $Date: 2005/11/12 02:13:49 $ $RCSfile: my3126.c,v $ $Revision: 1.15 $ */
#include "cphy.h"
#include "elmer0.h"
#include "suni1x10gexp_regs.h"
/* Port Reset */
static int my3126_reset(struct cphy *cphy, int wait)
{
/*
* This can be done through registers. It is not required since
* a full chip reset is used.
*/
return (0);
}
static int my3126_interrupt_enable(struct cphy *cphy)
{
schedule_delayed_work(&cphy->phy_update, HZ/30);
t1_tpi_read(cphy->adapter, A_ELMER0_GPO, &cphy->elmer_gpo);
return (0);
}
static int my3126_interrupt_disable(struct cphy *cphy)
{
cancel_rearming_delayed_work(&cphy->phy_update);
return (0);
}
static int my3126_interrupt_clear(struct cphy *cphy)
{
return (0);
}
#define OFFSET(REG_ADDR) (REG_ADDR << 2)
static int my3126_interrupt_handler(struct cphy *cphy)
{
u32 val;
u16 val16;
u16 status;
u32 act_count;
adapter_t *adapter;
adapter = cphy->adapter;
if (cphy->count == 50) {
mdio_read(cphy, 0x1, 0x1, &val);
val16 = (u16) val;
status = cphy->bmsr ^ val16;
if (status & BMSR_LSTATUS)
t1_link_changed(adapter, 0);
cphy->bmsr = val16;
/* We have only enabled link change interrupts so it
must be that
*/
cphy->count = 0;
}
t1_tpi_write(adapter, OFFSET(SUNI1x10GEXP_REG_MSTAT_CONTROL),
SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
t1_tpi_read(adapter,
OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW), &act_count);
t1_tpi_read(adapter,
OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW), &val);
act_count += val;
/* Populate elmer_gpo with the register value */
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
cphy->elmer_gpo = val;
if ( (val & (1 << 8)) || (val & (1 << 19)) ||
(cphy->act_count == act_count) || cphy->act_on ) {
if (is_T2(adapter))
val |= (1 << 9);
else if (t1_is_T1B(adapter))
val |= (1 << 20);
cphy->act_on = 0;
} else {
if (is_T2(adapter))
val &= ~(1 << 9);
else if (t1_is_T1B(adapter))
val &= ~(1 << 20);
cphy->act_on = 1;
}
t1_tpi_write(adapter, A_ELMER0_GPO, val);
cphy->elmer_gpo = val;
cphy->act_count = act_count;
cphy->count++;
return cphy_cause_link_change;
}
static void my3216_poll(void *arg)
{
my3126_interrupt_handler(arg);
}
static int my3126_set_loopback(struct cphy *cphy, int on)
{
return (0);
}
/* To check the activity LED */
static int my3126_get_link_status(struct cphy *cphy,
int *link_ok, int *speed, int *duplex, int *fc)
{
u32 val;
u16 val16;
adapter_t *adapter;
adapter = cphy->adapter;
mdio_read(cphy, 0x1, 0x1, &val);
val16 = (u16) val;
/* Populate elmer_gpo with the register value */
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
cphy->elmer_gpo = val;
*link_ok = (val16 & BMSR_LSTATUS);
if (*link_ok) {
/* Turn on the LED. */
if (is_T2(adapter))
val &= ~(1 << 8);
else if (t1_is_T1B(adapter))
val &= ~(1 << 19);
} else {
/* Turn off the LED. */
if (is_T2(adapter))
val |= (1 << 8);
else if (t1_is_T1B(adapter))
val |= (1 << 19);
}
t1_tpi_write(adapter, A_ELMER0_GPO, val);
cphy->elmer_gpo = val;
*speed = SPEED_10000;
*duplex = DUPLEX_FULL;
/* need to add flow control */
if (fc)
*fc = PAUSE_RX | PAUSE_TX;
return (0);
}
static void my3126_destroy(struct cphy *cphy)
{
kfree(cphy);
}
static struct cphy_ops my3126_ops = {
.destroy = my3126_destroy,
.reset = my3126_reset,
.interrupt_enable = my3126_interrupt_enable,
.interrupt_disable = my3126_interrupt_disable,
.interrupt_clear = my3126_interrupt_clear,
.interrupt_handler = my3126_interrupt_handler,
.get_link_status = my3126_get_link_status,
.set_loopback = my3126_set_loopback,
};
static struct cphy *my3126_phy_create(adapter_t *adapter,
int phy_addr, struct mdio_ops *mdio_ops)
{
struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
if (cphy)
cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops);
INIT_WORK(&cphy->phy_update, my3216_poll, cphy);
cphy->bmsr = 0;
return (cphy);
}
/* Chip Reset */
static int my3126_phy_reset(adapter_t * adapter)
{
u32 val;
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val &= ~4;
t1_tpi_write(adapter, A_ELMER0_GPO, val);
msleep(100);
t1_tpi_write(adapter, A_ELMER0_GPO, val | 4);
msleep(1000);
/* Now lets enable the Laser. Delay 100us */
t1_tpi_read(adapter, A_ELMER0_GPO, &val);
val |= 0x8000;
t1_tpi_write(adapter, A_ELMER0_GPO, val);
udelay(100);
return (0);
}
struct gphy t1_my3126_ops = {
my3126_phy_create,
my3126_phy_reset
};
...@@ -88,6 +88,8 @@ enum { /* RMON registers */ ...@@ -88,6 +88,8 @@ enum { /* RMON registers */
RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW, RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW,
RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW, RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW,
RxUndersizedFrames = SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW, RxUndersizedFrames = SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW,
RxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_25_LOW,
RxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_26_LOW,
TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW, TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW,
TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW, TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW,
...@@ -95,7 +97,9 @@ enum { /* RMON registers */ ...@@ -95,7 +97,9 @@ enum { /* RMON registers */
TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW, TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW,
TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW, TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW,
TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW, TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW,
TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW,
TxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_51_LOW,
TxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_52_LOW
}; };
struct _cmac_instance { struct _cmac_instance {
...@@ -265,6 +269,8 @@ static int pm3393_interrupt_handler(struct cmac *cmac) ...@@ -265,6 +269,8 @@ static int pm3393_interrupt_handler(struct cmac *cmac)
/* Read the master interrupt status register. */ /* Read the master interrupt status register. */
pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
&master_intr_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 */ /* TBD XXX Lets just clear everything for now */
pm3393_interrupt_clear(cmac); pm3393_interrupt_clear(cmac);
...@@ -307,11 +313,7 @@ static int pm3393_enable_port(struct cmac *cmac, int which) ...@@ -307,11 +313,7 @@ static int pm3393_enable_port(struct cmac *cmac, int which)
* The PHY doesn't give us link status indication on its own so have * The PHY doesn't give us link status indication on its own so have
* the link management code query it instead. * the link management code query it instead.
*/ */
{ t1_link_changed(cmac->adapter, 0);
extern void link_changed(adapter_t *adapter, int port_id);
link_changed(cmac->adapter, 0);
}
return 0; return 0;
} }
...@@ -519,6 +521,8 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, ...@@ -519,6 +521,8 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
RMON_UPDATE(mac, RxJabbers, RxJabberErrors); RMON_UPDATE(mac, RxJabbers, RxJabberErrors);
RMON_UPDATE(mac, RxFragments, RxRuntErrors); RMON_UPDATE(mac, RxFragments, RxRuntErrors);
RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors); RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors);
RMON_UPDATE(mac, RxJumboFramesReceivedOK, RxJumboFramesOK);
RMON_UPDATE(mac, RxJumboOctetsReceivedOK, RxJumboOctetsOK);
/* Tx stats */ /* Tx stats */
RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK); RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK);
...@@ -529,6 +533,8 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, ...@@ -529,6 +533,8 @@ static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK); RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK);
RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK); RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK);
RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames); RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames);
RMON_UPDATE(mac, TxJumboFramesReceivedOK, TxJumboFramesOK);
RMON_UPDATE(mac, TxJumboOctetsReceivedOK, TxJumboOctetsOK);
return &mac->stats; return &mac->stats;
} }
...@@ -814,6 +820,12 @@ static int pm3393_mac_reset(adapter_t * adapter) ...@@ -814,6 +820,12 @@ static int pm3393_mac_reset(adapter_t * adapter)
successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
&& is_xaui_mabc_pll_locked); && 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; return successful_reset ? 0 : 1;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -92,5 +92,9 @@ void t1_sge_intr_disable(struct sge *); ...@@ -92,5 +92,9 @@ void t1_sge_intr_disable(struct sge *);
void t1_sge_intr_clear(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_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); const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port);
void t1_sched_set_max_avail_bytes(struct sge *, unsigned int);
void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int);
unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int,
unsigned int);
#endif /* _CXGB_SGE_H_ */ #endif /* _CXGB_SGE_H_ */
This diff is collapsed.
This diff is collapsed.
/* $Date: 2006/02/07 04:21:54 $ $RCSfile: tp.c,v $ $Revision: 1.73 $ */
#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;
writel(val, ap->regs + A_TP_IN_CONFIG);
writel(F_TP_OUT_CSPI_CPL |
F_TP_OUT_ESPI_ETHERNET |
F_TP_OUT_ESPI_GENERATE_IP_CSUM |
F_TP_OUT_ESPI_GENERATE_TCP_CSUM,
ap->regs + A_TP_OUT_CONFIG);
writel(V_IP_TTL(64) |
F_PATH_MTU /* IP DF bit */ |
V_5TUPLE_LOOKUP(p->use_5tuple_mode) |
V_SYN_COOKIE_PARAMETER(29),
ap->regs + A_TP_GLOBAL_CONFIG);
/*
* Enable pause frame deadlock prevention.
*/
if (is_T2(ap) && ap->params.nports > 1) {
u32 drop_ticks = DROP_MSEC * (tp_clk / 1000);
writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR |
V_DROP_TICKS_CNT(drop_ticks) |
V_NUM_PKTS_DROPPED(DROP_PKTS_CNT),
ap->regs + A_TP_TX_DROP_CONFIG);
}
}
}
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 = kzalloc(sizeof(*tp), GFP_KERNEL);
if (!tp)
return NULL;
tp->adapter = adapter;
return tp;
}
void t1_tp_intr_enable(struct petp *tp)
{
u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE);
{
/* We don't use any TP interrupts */
writel(0, tp->adapter->regs + A_TP_INT_ENABLE);
writel(tp_intr | F_PL_INTR_TP,
tp->adapter->regs + A_PL_ENABLE);
}
}
void t1_tp_intr_disable(struct petp *tp)
{
u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE);
{
writel(0, tp->adapter->regs + A_TP_INT_ENABLE);
writel(tp_intr & ~F_PL_INTR_TP,
tp->adapter->regs + A_PL_ENABLE);
}
}
void t1_tp_intr_clear(struct petp *tp)
{
writel(0xffffffff, tp->adapter->regs + A_TP_INT_CAUSE);
writel(F_PL_INTR_TP, tp->adapter->regs + A_PL_CAUSE);
}
int t1_tp_intr_handler(struct petp *tp)
{
u32 cause;
cause = readl(tp->adapter->regs + A_TP_INT_CAUSE);
writel(cause, tp->adapter->regs + A_TP_INT_CAUSE);
return 0;
}
static void set_csum_offload(struct petp *tp, u32 csum_bit, int enable)
{
u32 val = readl(tp->adapter->regs + A_TP_GLOBAL_CONFIG);
if (enable)
val |= csum_bit;
else
val &= ~csum_bit;
writel(val, tp->adapter->regs + A_TP_GLOBAL_CONFIG);
}
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)
{
adapter_t *adapter = tp->adapter;
tp_init(adapter, p, tp_clk);
writel(F_TP_RESET, adapter->regs + A_TP_RESET);
return 0;
}
/* $Date: 2005/03/07 23:59:05 $ $RCSfile: tp.h,v $ $Revision: 1.20 $ */
#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
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment