1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI" /* cphy.h */
27
28 #ifndef CHELSIO_CPHY_H
29 #define CHELSIO_CPHY_H
30
31 #include "common.h"
32
33 struct mdio_ops {
34 void (*init)(adapter_t *adapter, const struct board_info *bi);
35 int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
36 int reg_addr, unsigned int *val);
37 int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
38 int reg_addr, unsigned int val);
39 };
40
41 /* PHY interrupt types */
42 enum {
43 cphy_cause_link_change = 0x1,
44 cphy_cause_error = 0x2
45 };
46
47 enum {
48 PHY_LINK_UP = 0x1,
49 PHY_AUTONEG_RDY = 0x2,
50 PHY_AUTONEG_EN = 0x4
51 };
52
53 struct cphy;
54
55 /* PHY operations */
56 struct cphy_ops {
57 void (*destroy)(struct cphy *);
58 int (*reset)(struct cphy *, int wait);
59
60 int (*interrupt_enable)(struct cphy *);
61 int (*interrupt_disable)(struct cphy *);
62 int (*interrupt_clear)(struct cphy *);
63 int (*interrupt_handler)(struct cphy *);
64
65 int (*autoneg_enable)(struct cphy *);
66 int (*autoneg_disable)(struct cphy *);
67 int (*autoneg_restart)(struct cphy *);
68
69 int (*advertise)(struct cphy *phy, unsigned int advertise_map);
70 int (*set_loopback)(struct cphy *, int on);
71 int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
72 int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
73 int *duplex, int *fc);
74 };
75
76 /* A PHY instance */
77 struct cphy {
78 int addr; /* PHY address */
79 int state; /* Link status state machine */
80 adapter_t *adapter; /* associated adapter */
81
82 ch_cyclic_t phy_update_cyclic;
83
84 u16 bmsr;
85 int count;
86 int act_count;
87 int act_on;
88
89 u32 elmer_gpo;
90
91 struct cphy_ops *ops; /* PHY operations */
92 int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
93 int reg_addr, unsigned int *val);
94 int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
95 int reg_addr, unsigned int val);
96 struct cphy_instance *instance;
97 };
98
99 /* Convenience MDIO read/write wrappers */
mdio_read(struct cphy * cphy,int mmd,int reg,unsigned int * valp)100 static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
101 unsigned int *valp)
102 {
103 return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
104 }
105
mdio_write(struct cphy * cphy,int mmd,int reg,unsigned int val)106 static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
107 unsigned int val)
108 {
109 return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
110 }
111
simple_mdio_read(struct cphy * cphy,int reg,unsigned int * valp)112 static inline int simple_mdio_read(struct cphy *cphy, int reg,
113 unsigned int *valp)
114 {
115 return mdio_read(cphy, 0, reg, valp);
116 }
117
simple_mdio_write(struct cphy * cphy,int reg,unsigned int val)118 static inline int simple_mdio_write(struct cphy *cphy, int reg,
119 unsigned int val)
120 {
121 return mdio_write(cphy, 0, reg, val);
122 }
123
124 /* Convenience initializer */
cphy_init(struct cphy * phy,adapter_t * adapter,int phy_addr,struct cphy_ops * phy_ops,struct mdio_ops * mdio_ops)125 static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
126 int phy_addr, struct cphy_ops *phy_ops,
127 struct mdio_ops *mdio_ops)
128 {
129 phy->adapter = adapter;
130 phy->addr = phy_addr;
131 phy->ops = phy_ops;
132 if (mdio_ops) {
133 phy->mdio_read = mdio_ops->read;
134 phy->mdio_write = mdio_ops->write;
135 }
136 }
137
138 /* Operations of the PHY-instance factory */
139 struct gphy {
140 /* Construct a PHY instance with the given PHY address */
141 struct cphy *(*create)(adapter_t *adapter, int phy_addr,
142 struct mdio_ops *mdio_ops);
143
144 /*
145 * Reset the PHY chip. This resets the whole PHY chip, not individual
146 * ports.
147 */
148 int (*reset)(adapter_t *adapter);
149 };
150
151 extern struct gphy t1_my3126_ops;
152 extern struct gphy t1_mv88e1xxx_ops;
153 extern struct gphy t1_xpak_ops;
154 extern struct gphy t1_mv88x201x_ops;
155 extern struct gphy t1_dummy_phy_ops;
156 #endif
157