0001
0002
0003 #include "cphy.h"
0004 #include "elmer0.h"
0005 #include "suni1x10gexp_regs.h"
0006
0007
0008 static int my3126_reset(struct cphy *cphy, int wait)
0009 {
0010
0011
0012
0013
0014 return 0;
0015 }
0016
0017 static int my3126_interrupt_enable(struct cphy *cphy)
0018 {
0019 schedule_delayed_work(&cphy->phy_update, HZ/30);
0020 t1_tpi_read(cphy->adapter, A_ELMER0_GPO, &cphy->elmer_gpo);
0021 return 0;
0022 }
0023
0024 static int my3126_interrupt_disable(struct cphy *cphy)
0025 {
0026 cancel_delayed_work_sync(&cphy->phy_update);
0027 return 0;
0028 }
0029
0030 static int my3126_interrupt_clear(struct cphy *cphy)
0031 {
0032 return 0;
0033 }
0034
0035 #define OFFSET(REG_ADDR) (REG_ADDR << 2)
0036
0037 static int my3126_interrupt_handler(struct cphy *cphy)
0038 {
0039 u32 val;
0040 u16 val16;
0041 u16 status;
0042 u32 act_count;
0043 adapter_t *adapter;
0044 adapter = cphy->adapter;
0045
0046 if (cphy->count == 50) {
0047 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
0048 val16 = (u16) val;
0049 status = cphy->bmsr ^ val16;
0050
0051 if (status & MDIO_STAT1_LSTATUS)
0052 t1_link_changed(adapter, 0);
0053 cphy->bmsr = val16;
0054
0055
0056
0057
0058 cphy->count = 0;
0059 }
0060
0061 t1_tpi_write(adapter, OFFSET(SUNI1x10GEXP_REG_MSTAT_CONTROL),
0062 SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
0063 t1_tpi_read(adapter,
0064 OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW), &act_count);
0065 t1_tpi_read(adapter,
0066 OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW), &val);
0067 act_count += val;
0068
0069
0070 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
0071 cphy->elmer_gpo = val;
0072
0073 if ( (val & (1 << 8)) || (val & (1 << 19)) ||
0074 (cphy->act_count == act_count) || cphy->act_on ) {
0075 if (is_T2(adapter))
0076 val |= (1 << 9);
0077 else if (t1_is_T1B(adapter))
0078 val |= (1 << 20);
0079 cphy->act_on = 0;
0080 } else {
0081 if (is_T2(adapter))
0082 val &= ~(1 << 9);
0083 else if (t1_is_T1B(adapter))
0084 val &= ~(1 << 20);
0085 cphy->act_on = 1;
0086 }
0087
0088 t1_tpi_write(adapter, A_ELMER0_GPO, val);
0089
0090 cphy->elmer_gpo = val;
0091 cphy->act_count = act_count;
0092 cphy->count++;
0093
0094 return cphy_cause_link_change;
0095 }
0096
0097 static void my3126_poll(struct work_struct *work)
0098 {
0099 struct cphy *cphy = container_of(work, struct cphy, phy_update.work);
0100
0101 my3126_interrupt_handler(cphy);
0102 }
0103
0104 static int my3126_set_loopback(struct cphy *cphy, int on)
0105 {
0106 return 0;
0107 }
0108
0109
0110 static int my3126_get_link_status(struct cphy *cphy,
0111 int *link_ok, int *speed, int *duplex, int *fc)
0112 {
0113 u32 val;
0114 u16 val16;
0115 adapter_t *adapter;
0116
0117 adapter = cphy->adapter;
0118 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
0119 val16 = (u16) val;
0120
0121
0122 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
0123 cphy->elmer_gpo = val;
0124
0125 *link_ok = (val16 & MDIO_STAT1_LSTATUS);
0126
0127 if (*link_ok) {
0128
0129 if (is_T2(adapter))
0130 val &= ~(1 << 8);
0131 else if (t1_is_T1B(adapter))
0132 val &= ~(1 << 19);
0133 } else {
0134
0135 if (is_T2(adapter))
0136 val |= (1 << 8);
0137 else if (t1_is_T1B(adapter))
0138 val |= (1 << 19);
0139 }
0140
0141 t1_tpi_write(adapter, A_ELMER0_GPO, val);
0142 cphy->elmer_gpo = val;
0143 *speed = SPEED_10000;
0144 *duplex = DUPLEX_FULL;
0145
0146
0147 if (fc)
0148 *fc = PAUSE_RX | PAUSE_TX;
0149
0150 return 0;
0151 }
0152
0153 static void my3126_destroy(struct cphy *cphy)
0154 {
0155 kfree(cphy);
0156 }
0157
0158 static const struct cphy_ops my3126_ops = {
0159 .destroy = my3126_destroy,
0160 .reset = my3126_reset,
0161 .interrupt_enable = my3126_interrupt_enable,
0162 .interrupt_disable = my3126_interrupt_disable,
0163 .interrupt_clear = my3126_interrupt_clear,
0164 .interrupt_handler = my3126_interrupt_handler,
0165 .get_link_status = my3126_get_link_status,
0166 .set_loopback = my3126_set_loopback,
0167 .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
0168 MDIO_DEVS_PHYXS),
0169 };
0170
0171 static struct cphy *my3126_phy_create(struct net_device *dev,
0172 int phy_addr, const struct mdio_ops *mdio_ops)
0173 {
0174 struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
0175
0176 if (!cphy)
0177 return NULL;
0178
0179 cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops);
0180 INIT_DELAYED_WORK(&cphy->phy_update, my3126_poll);
0181 cphy->bmsr = 0;
0182
0183 return cphy;
0184 }
0185
0186
0187 static int my3126_phy_reset(adapter_t * adapter)
0188 {
0189 u32 val;
0190
0191 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
0192 val &= ~4;
0193 t1_tpi_write(adapter, A_ELMER0_GPO, val);
0194 msleep(100);
0195
0196 t1_tpi_write(adapter, A_ELMER0_GPO, val | 4);
0197 msleep(1000);
0198
0199
0200 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
0201 val |= 0x8000;
0202 t1_tpi_write(adapter, A_ELMER0_GPO, val);
0203 udelay(100);
0204 return 0;
0205 }
0206
0207 const struct gphy t1_my3126_ops = {
0208 .create = my3126_phy_create,
0209 .reset = my3126_phy_reset
0210 };