~ubuntu-branches/ubuntu/utopic/linux-ti-omap/utopic

« back to all changes in this revision

Viewing changes to drivers/net/chelsio/my3126.c

  • Committer: Bazaar Package Importer
  • Author(s): Amit Kucheria, Amit Kucheria
  • Date: 2010-03-10 02:28:15 UTC
  • Revision ID: james.westby@ubuntu.com-20100310022815-7sd3gwvn5kenaq33
Tags: 2.6.33-500.1
[ Amit Kucheria ]

* Initial release of a 2.6.33-based OMAP kernel
* UBUNTU: [Upstream] Fix omap 1-wire driver compilation
* UBUNTU: ubuntu: AppArmor -- update to mainline 2010-03-04

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Date: 2005/11/12 02:13:49 $ $RCSfile: my3126.c,v $ $Revision: 1.15 $ */
 
2
#include "cphy.h"
 
3
#include "elmer0.h"
 
4
#include "suni1x10gexp_regs.h"
 
5
 
 
6
/* Port Reset */
 
7
static int my3126_reset(struct cphy *cphy, int wait)
 
8
{
 
9
        /*
 
10
         * This can be done through registers.  It is not required since
 
11
         * a full chip reset is used.
 
12
         */
 
13
        return 0;
 
14
}
 
15
 
 
16
static int my3126_interrupt_enable(struct cphy *cphy)
 
17
{
 
18
        schedule_delayed_work(&cphy->phy_update, HZ/30);
 
19
        t1_tpi_read(cphy->adapter, A_ELMER0_GPO, &cphy->elmer_gpo);
 
20
        return 0;
 
21
}
 
22
 
 
23
static int my3126_interrupt_disable(struct cphy *cphy)
 
24
{
 
25
        cancel_rearming_delayed_work(&cphy->phy_update);
 
26
        return 0;
 
27
}
 
28
 
 
29
static int my3126_interrupt_clear(struct cphy *cphy)
 
30
{
 
31
        return 0;
 
32
}
 
33
 
 
34
#define OFFSET(REG_ADDR)    (REG_ADDR << 2)
 
35
 
 
36
static int my3126_interrupt_handler(struct cphy *cphy)
 
37
{
 
38
        u32 val;
 
39
        u16 val16;
 
40
        u16 status;
 
41
        u32 act_count;
 
42
        adapter_t *adapter;
 
43
        adapter = cphy->adapter;
 
44
 
 
45
        if (cphy->count == 50) {
 
46
                cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
 
47
                val16 = (u16) val;
 
48
                status = cphy->bmsr ^ val16;
 
49
 
 
50
                if (status & MDIO_STAT1_LSTATUS)
 
51
                        t1_link_changed(adapter, 0);
 
52
                cphy->bmsr = val16;
 
53
 
 
54
                /* We have only enabled link change interrupts so it
 
55
                   must be that
 
56
                 */
 
57
                cphy->count = 0;
 
58
        }
 
59
 
 
60
        t1_tpi_write(adapter, OFFSET(SUNI1x10GEXP_REG_MSTAT_CONTROL),
 
61
                SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
 
62
        t1_tpi_read(adapter,
 
63
                OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW), &act_count);
 
64
        t1_tpi_read(adapter,
 
65
                OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW), &val);
 
66
        act_count += val;
 
67
 
 
68
        /* Populate elmer_gpo with the register value */
 
69
        t1_tpi_read(adapter, A_ELMER0_GPO, &val);
 
70
        cphy->elmer_gpo = val;
 
71
 
 
72
        if ( (val & (1 << 8)) || (val & (1 << 19)) ||
 
73
             (cphy->act_count == act_count) || cphy->act_on ) {
 
74
                if (is_T2(adapter))
 
75
                        val |= (1 << 9);
 
76
                else if (t1_is_T1B(adapter))
 
77
                        val |= (1 << 20);
 
78
                cphy->act_on = 0;
 
79
        } else {
 
80
                if (is_T2(adapter))
 
81
                        val &= ~(1 << 9);
 
82
                else if (t1_is_T1B(adapter))
 
83
                        val &= ~(1 << 20);
 
84
                cphy->act_on = 1;
 
85
        }
 
86
 
 
87
        t1_tpi_write(adapter, A_ELMER0_GPO, val);
 
88
 
 
89
        cphy->elmer_gpo = val;
 
90
        cphy->act_count = act_count;
 
91
        cphy->count++;
 
92
 
 
93
        return cphy_cause_link_change;
 
94
}
 
95
 
 
96
static void my3216_poll(struct work_struct *work)
 
97
{
 
98
        struct cphy *cphy = container_of(work, struct cphy, phy_update.work);
 
99
 
 
100
        my3126_interrupt_handler(cphy);
 
101
}
 
102
 
 
103
static int my3126_set_loopback(struct cphy *cphy, int on)
 
104
{
 
105
        return 0;
 
106
}
 
107
 
 
108
/* To check the activity LED */
 
109
static int my3126_get_link_status(struct cphy *cphy,
 
110
                        int *link_ok, int *speed, int *duplex, int *fc)
 
111
{
 
112
        u32 val;
 
113
        u16 val16;
 
114
        adapter_t *adapter;
 
115
 
 
116
        adapter = cphy->adapter;
 
117
        cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
 
118
        val16 = (u16) val;
 
119
 
 
120
        /* Populate elmer_gpo with the register value */
 
121
        t1_tpi_read(adapter, A_ELMER0_GPO, &val);
 
122
        cphy->elmer_gpo = val;
 
123
 
 
124
        *link_ok = (val16 & MDIO_STAT1_LSTATUS);
 
125
 
 
126
        if (*link_ok) {
 
127
                /* Turn on the LED. */
 
128
                if (is_T2(adapter))
 
129
                         val &= ~(1 << 8);
 
130
                else if (t1_is_T1B(adapter))
 
131
                         val &= ~(1 << 19);
 
132
        } else {
 
133
                /* Turn off the LED. */
 
134
                if (is_T2(adapter))
 
135
                         val |= (1 << 8);
 
136
                else if (t1_is_T1B(adapter))
 
137
                         val |= (1 << 19);
 
138
        }
 
139
 
 
140
        t1_tpi_write(adapter, A_ELMER0_GPO, val);
 
141
        cphy->elmer_gpo = val;
 
142
        *speed = SPEED_10000;
 
143
        *duplex = DUPLEX_FULL;
 
144
 
 
145
        /* need to add flow control */
 
146
        if (fc)
 
147
                *fc = PAUSE_RX | PAUSE_TX;
 
148
 
 
149
        return 0;
 
150
}
 
151
 
 
152
static void my3126_destroy(struct cphy *cphy)
 
153
{
 
154
        kfree(cphy);
 
155
}
 
156
 
 
157
static struct cphy_ops my3126_ops = {
 
158
        .destroy                = my3126_destroy,
 
159
        .reset                  = my3126_reset,
 
160
        .interrupt_enable       = my3126_interrupt_enable,
 
161
        .interrupt_disable      = my3126_interrupt_disable,
 
162
        .interrupt_clear        = my3126_interrupt_clear,
 
163
        .interrupt_handler      = my3126_interrupt_handler,
 
164
        .get_link_status        = my3126_get_link_status,
 
165
        .set_loopback           = my3126_set_loopback,
 
166
        .mmds                   = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
 
167
                                   MDIO_DEVS_PHYXS),
 
168
};
 
169
 
 
170
static struct cphy *my3126_phy_create(struct net_device *dev,
 
171
                        int phy_addr, const struct mdio_ops *mdio_ops)
 
172
{
 
173
        struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
 
174
 
 
175
        if (!cphy)
 
176
                return NULL;
 
177
 
 
178
        cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops);
 
179
        INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll);
 
180
        cphy->bmsr = 0;
 
181
 
 
182
        return cphy;
 
183
}
 
184
 
 
185
/* Chip Reset */
 
186
static int my3126_phy_reset(adapter_t * adapter)
 
187
{
 
188
        u32 val;
 
189
 
 
190
        t1_tpi_read(adapter, A_ELMER0_GPO, &val);
 
191
        val &= ~4;
 
192
        t1_tpi_write(adapter, A_ELMER0_GPO, val);
 
193
        msleep(100);
 
194
 
 
195
        t1_tpi_write(adapter, A_ELMER0_GPO, val | 4);
 
196
        msleep(1000);
 
197
 
 
198
        /* Now lets enable the Laser. Delay 100us */
 
199
        t1_tpi_read(adapter, A_ELMER0_GPO, &val);
 
200
        val |= 0x8000;
 
201
        t1_tpi_write(adapter, A_ELMER0_GPO, val);
 
202
        udelay(100);
 
203
        return 0;
 
204
}
 
205
 
 
206
const struct gphy t1_my3126_ops = {
 
207
        .create = my3126_phy_create,
 
208
        .reset = my3126_phy_reset
 
209
};