1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Altera 10/100/1000 triple speed ethernet mac driver
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2008 Altera Corporation.
5*4882a593Smuzhiyun * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
8*4882a593Smuzhiyun * it under the terms of the GNU General Public License version 2 as
9*4882a593Smuzhiyun * published by the Free Software Foundation.
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <dm.h>
13*4882a593Smuzhiyun #include <errno.h>
14*4882a593Smuzhiyun #include <fdt_support.h>
15*4882a593Smuzhiyun #include <memalign.h>
16*4882a593Smuzhiyun #include <miiphy.h>
17*4882a593Smuzhiyun #include <net.h>
18*4882a593Smuzhiyun #include <asm/cache.h>
19*4882a593Smuzhiyun #include <asm/dma-mapping.h>
20*4882a593Smuzhiyun #include <asm/io.h>
21*4882a593Smuzhiyun #include "altera_tse.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
24*4882a593Smuzhiyun
alt_sgdma_construct_descriptor(struct alt_sgdma_descriptor * desc,struct alt_sgdma_descriptor * next,void * read_addr,void * write_addr,u16 length_or_eop,int generate_eop,int read_fixed,int write_fixed_or_sop)25*4882a593Smuzhiyun static inline void alt_sgdma_construct_descriptor(
26*4882a593Smuzhiyun struct alt_sgdma_descriptor *desc,
27*4882a593Smuzhiyun struct alt_sgdma_descriptor *next,
28*4882a593Smuzhiyun void *read_addr,
29*4882a593Smuzhiyun void *write_addr,
30*4882a593Smuzhiyun u16 length_or_eop,
31*4882a593Smuzhiyun int generate_eop,
32*4882a593Smuzhiyun int read_fixed,
33*4882a593Smuzhiyun int write_fixed_or_sop)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun u8 val;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /*
38*4882a593Smuzhiyun * Mark the "next" descriptor as "not" owned by hardware. This prevents
39*4882a593Smuzhiyun * The SGDMA controller from continuing to process the chain.
40*4882a593Smuzhiyun */
41*4882a593Smuzhiyun next->descriptor_control = next->descriptor_control &
42*4882a593Smuzhiyun ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun memset(desc, 0, sizeof(struct alt_sgdma_descriptor));
45*4882a593Smuzhiyun desc->source = virt_to_phys(read_addr);
46*4882a593Smuzhiyun desc->destination = virt_to_phys(write_addr);
47*4882a593Smuzhiyun desc->next = virt_to_phys(next);
48*4882a593Smuzhiyun desc->bytes_to_transfer = length_or_eop;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun /*
51*4882a593Smuzhiyun * Set the descriptor control block as follows:
52*4882a593Smuzhiyun * - Set "owned by hardware" bit
53*4882a593Smuzhiyun * - Optionally set "generate EOP" bit
54*4882a593Smuzhiyun * - Optionally set the "read from fixed address" bit
55*4882a593Smuzhiyun * - Optionally set the "write to fixed address bit (which serves
56*4882a593Smuzhiyun * serves as a "generate SOP" control bit in memory-to-stream mode).
57*4882a593Smuzhiyun * - Set the 4-bit atlantic channel, if specified
58*4882a593Smuzhiyun *
59*4882a593Smuzhiyun * Note this step is performed after all other descriptor information
60*4882a593Smuzhiyun * has been filled out so that, if the controller already happens to be
61*4882a593Smuzhiyun * pointing at this descriptor, it will not run (via the "owned by
62*4882a593Smuzhiyun * hardware" bit) until all other descriptor has been set up.
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun val = ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
65*4882a593Smuzhiyun if (generate_eop)
66*4882a593Smuzhiyun val |= ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK;
67*4882a593Smuzhiyun if (read_fixed)
68*4882a593Smuzhiyun val |= ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK;
69*4882a593Smuzhiyun if (write_fixed_or_sop)
70*4882a593Smuzhiyun val |= ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK;
71*4882a593Smuzhiyun desc->descriptor_control = val;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
alt_sgdma_wait_transfer(struct alt_sgdma_registers * regs)74*4882a593Smuzhiyun static int alt_sgdma_wait_transfer(struct alt_sgdma_registers *regs)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun int status;
77*4882a593Smuzhiyun ulong ctime;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /* Wait for the descriptor (chain) to complete */
80*4882a593Smuzhiyun ctime = get_timer(0);
81*4882a593Smuzhiyun while (1) {
82*4882a593Smuzhiyun status = readl(®s->status);
83*4882a593Smuzhiyun if (!(status & ALT_SGDMA_STATUS_BUSY_MSK))
84*4882a593Smuzhiyun break;
85*4882a593Smuzhiyun if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
86*4882a593Smuzhiyun status = -ETIMEDOUT;
87*4882a593Smuzhiyun debug("sgdma timeout\n");
88*4882a593Smuzhiyun break;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /* Clear Run */
93*4882a593Smuzhiyun writel(0, ®s->control);
94*4882a593Smuzhiyun /* Clear status */
95*4882a593Smuzhiyun writel(0xff, ®s->status);
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun return status;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
alt_sgdma_start_transfer(struct alt_sgdma_registers * regs,struct alt_sgdma_descriptor * desc)100*4882a593Smuzhiyun static int alt_sgdma_start_transfer(struct alt_sgdma_registers *regs,
101*4882a593Smuzhiyun struct alt_sgdma_descriptor *desc)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun u32 val;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* Point the controller at the descriptor */
106*4882a593Smuzhiyun writel(virt_to_phys(desc), ®s->next_descriptor_pointer);
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /*
109*4882a593Smuzhiyun * Set up SGDMA controller to:
110*4882a593Smuzhiyun * - Disable interrupt generation
111*4882a593Smuzhiyun * - Run once a valid descriptor is written to controller
112*4882a593Smuzhiyun * - Stop on an error with any particular descriptor
113*4882a593Smuzhiyun */
114*4882a593Smuzhiyun val = ALT_SGDMA_CONTROL_RUN_MSK | ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK;
115*4882a593Smuzhiyun writel(val, ®s->control);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun return 0;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
tse_adjust_link(struct altera_tse_priv * priv,struct phy_device * phydev)120*4882a593Smuzhiyun static void tse_adjust_link(struct altera_tse_priv *priv,
121*4882a593Smuzhiyun struct phy_device *phydev)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
124*4882a593Smuzhiyun u32 refvar;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (!phydev->link) {
127*4882a593Smuzhiyun debug("%s: No link.\n", phydev->dev->name);
128*4882a593Smuzhiyun return;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun refvar = readl(&mac_dev->command_config);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun if (phydev->duplex)
134*4882a593Smuzhiyun refvar |= ALTERA_TSE_CMD_HD_ENA_MSK;
135*4882a593Smuzhiyun else
136*4882a593Smuzhiyun refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun switch (phydev->speed) {
139*4882a593Smuzhiyun case 1000:
140*4882a593Smuzhiyun refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK;
141*4882a593Smuzhiyun refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
142*4882a593Smuzhiyun break;
143*4882a593Smuzhiyun case 100:
144*4882a593Smuzhiyun refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
145*4882a593Smuzhiyun refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
146*4882a593Smuzhiyun break;
147*4882a593Smuzhiyun case 10:
148*4882a593Smuzhiyun refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
149*4882a593Smuzhiyun refvar |= ALTERA_TSE_CMD_ENA_10_MSK;
150*4882a593Smuzhiyun break;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun writel(refvar, &mac_dev->command_config);
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
altera_tse_send_sgdma(struct udevice * dev,void * packet,int length)155*4882a593Smuzhiyun static int altera_tse_send_sgdma(struct udevice *dev, void *packet, int length)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
158*4882a593Smuzhiyun struct alt_sgdma_descriptor *tx_desc = priv->tx_desc;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun alt_sgdma_construct_descriptor(
161*4882a593Smuzhiyun tx_desc,
162*4882a593Smuzhiyun tx_desc + 1,
163*4882a593Smuzhiyun packet, /* read addr */
164*4882a593Smuzhiyun NULL, /* write addr */
165*4882a593Smuzhiyun length, /* length or EOP ,will change for each tx */
166*4882a593Smuzhiyun 1, /* gen eop */
167*4882a593Smuzhiyun 0, /* read fixed */
168*4882a593Smuzhiyun 1 /* write fixed or sop */
169*4882a593Smuzhiyun );
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /* send the packet */
172*4882a593Smuzhiyun alt_sgdma_start_transfer(priv->sgdma_tx, tx_desc);
173*4882a593Smuzhiyun alt_sgdma_wait_transfer(priv->sgdma_tx);
174*4882a593Smuzhiyun debug("sent %d bytes\n", tx_desc->actual_bytes_transferred);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun return tx_desc->actual_bytes_transferred;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun
altera_tse_recv_sgdma(struct udevice * dev,int flags,uchar ** packetp)179*4882a593Smuzhiyun static int altera_tse_recv_sgdma(struct udevice *dev, int flags,
180*4882a593Smuzhiyun uchar **packetp)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
183*4882a593Smuzhiyun struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
184*4882a593Smuzhiyun int packet_length;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun if (rx_desc->descriptor_status &
187*4882a593Smuzhiyun ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
188*4882a593Smuzhiyun alt_sgdma_wait_transfer(priv->sgdma_rx);
189*4882a593Smuzhiyun packet_length = rx_desc->actual_bytes_transferred;
190*4882a593Smuzhiyun debug("recv %d bytes\n", packet_length);
191*4882a593Smuzhiyun *packetp = priv->rx_buf;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun return packet_length;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun return -EAGAIN;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
altera_tse_free_pkt_sgdma(struct udevice * dev,uchar * packet,int length)199*4882a593Smuzhiyun static int altera_tse_free_pkt_sgdma(struct udevice *dev, uchar *packet,
200*4882a593Smuzhiyun int length)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
203*4882a593Smuzhiyun struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun alt_sgdma_construct_descriptor(
206*4882a593Smuzhiyun rx_desc,
207*4882a593Smuzhiyun rx_desc + 1,
208*4882a593Smuzhiyun NULL, /* read addr */
209*4882a593Smuzhiyun priv->rx_buf, /* write addr */
210*4882a593Smuzhiyun 0, /* length or EOP */
211*4882a593Smuzhiyun 0, /* gen eop */
212*4882a593Smuzhiyun 0, /* read fixed */
213*4882a593Smuzhiyun 0 /* write fixed or sop */
214*4882a593Smuzhiyun );
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* setup the sgdma */
217*4882a593Smuzhiyun alt_sgdma_start_transfer(priv->sgdma_rx, rx_desc);
218*4882a593Smuzhiyun debug("recv setup\n");
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun return 0;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun
altera_tse_stop_mac(struct altera_tse_priv * priv)223*4882a593Smuzhiyun static void altera_tse_stop_mac(struct altera_tse_priv *priv)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
226*4882a593Smuzhiyun u32 status;
227*4882a593Smuzhiyun ulong ctime;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* reset the mac */
230*4882a593Smuzhiyun writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config);
231*4882a593Smuzhiyun ctime = get_timer(0);
232*4882a593Smuzhiyun while (1) {
233*4882a593Smuzhiyun status = readl(&mac_dev->command_config);
234*4882a593Smuzhiyun if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK))
235*4882a593Smuzhiyun break;
236*4882a593Smuzhiyun if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
237*4882a593Smuzhiyun debug("Reset mac timeout\n");
238*4882a593Smuzhiyun break;
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
altera_tse_stop_sgdma(struct udevice * dev)243*4882a593Smuzhiyun static void altera_tse_stop_sgdma(struct udevice *dev)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
246*4882a593Smuzhiyun struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
247*4882a593Smuzhiyun struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
248*4882a593Smuzhiyun struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
249*4882a593Smuzhiyun int ret;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /* clear rx desc & wait for sgdma to complete */
252*4882a593Smuzhiyun rx_desc->descriptor_control = 0;
253*4882a593Smuzhiyun writel(0, &rx_sgdma->control);
254*4882a593Smuzhiyun ret = alt_sgdma_wait_transfer(rx_sgdma);
255*4882a593Smuzhiyun if (ret == -ETIMEDOUT)
256*4882a593Smuzhiyun writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
257*4882a593Smuzhiyun &rx_sgdma->control);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun writel(0, &tx_sgdma->control);
260*4882a593Smuzhiyun ret = alt_sgdma_wait_transfer(tx_sgdma);
261*4882a593Smuzhiyun if (ret == -ETIMEDOUT)
262*4882a593Smuzhiyun writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
263*4882a593Smuzhiyun &tx_sgdma->control);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
msgdma_reset(struct msgdma_csr * csr)266*4882a593Smuzhiyun static void msgdma_reset(struct msgdma_csr *csr)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun u32 status;
269*4882a593Smuzhiyun ulong ctime;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /* Reset mSGDMA */
272*4882a593Smuzhiyun writel(MSGDMA_CSR_STAT_MASK, &csr->status);
273*4882a593Smuzhiyun writel(MSGDMA_CSR_CTL_RESET, &csr->control);
274*4882a593Smuzhiyun ctime = get_timer(0);
275*4882a593Smuzhiyun while (1) {
276*4882a593Smuzhiyun status = readl(&csr->status);
277*4882a593Smuzhiyun if (!(status & MSGDMA_CSR_STAT_RESETTING))
278*4882a593Smuzhiyun break;
279*4882a593Smuzhiyun if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
280*4882a593Smuzhiyun debug("Reset msgdma timeout\n");
281*4882a593Smuzhiyun break;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun /* Clear status */
285*4882a593Smuzhiyun writel(MSGDMA_CSR_STAT_MASK, &csr->status);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
msgdma_wait(struct msgdma_csr * csr)288*4882a593Smuzhiyun static u32 msgdma_wait(struct msgdma_csr *csr)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun u32 status;
291*4882a593Smuzhiyun ulong ctime;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun /* Wait for the descriptor to complete */
294*4882a593Smuzhiyun ctime = get_timer(0);
295*4882a593Smuzhiyun while (1) {
296*4882a593Smuzhiyun status = readl(&csr->status);
297*4882a593Smuzhiyun if (!(status & MSGDMA_CSR_STAT_BUSY))
298*4882a593Smuzhiyun break;
299*4882a593Smuzhiyun if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
300*4882a593Smuzhiyun debug("sgdma timeout\n");
301*4882a593Smuzhiyun break;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun /* Clear status */
305*4882a593Smuzhiyun writel(MSGDMA_CSR_STAT_MASK, &csr->status);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun return status;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
altera_tse_send_msgdma(struct udevice * dev,void * packet,int length)310*4882a593Smuzhiyun static int altera_tse_send_msgdma(struct udevice *dev, void *packet,
311*4882a593Smuzhiyun int length)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
314*4882a593Smuzhiyun struct msgdma_extended_desc *desc = priv->tx_desc;
315*4882a593Smuzhiyun u32 tx_buf = virt_to_phys(packet);
316*4882a593Smuzhiyun u32 status;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun writel(tx_buf, &desc->read_addr_lo);
319*4882a593Smuzhiyun writel(0, &desc->read_addr_hi);
320*4882a593Smuzhiyun writel(0, &desc->write_addr_lo);
321*4882a593Smuzhiyun writel(0, &desc->write_addr_hi);
322*4882a593Smuzhiyun writel(length, &desc->len);
323*4882a593Smuzhiyun writel(0, &desc->burst_seq_num);
324*4882a593Smuzhiyun writel(MSGDMA_DESC_TX_STRIDE, &desc->stride);
325*4882a593Smuzhiyun writel(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
326*4882a593Smuzhiyun status = msgdma_wait(priv->sgdma_tx);
327*4882a593Smuzhiyun debug("sent %d bytes, status %08x\n", length, status);
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun return 0;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
altera_tse_recv_msgdma(struct udevice * dev,int flags,uchar ** packetp)332*4882a593Smuzhiyun static int altera_tse_recv_msgdma(struct udevice *dev, int flags,
333*4882a593Smuzhiyun uchar **packetp)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
336*4882a593Smuzhiyun struct msgdma_csr *csr = priv->sgdma_rx;
337*4882a593Smuzhiyun struct msgdma_response *resp = priv->rx_resp;
338*4882a593Smuzhiyun u32 level, length, status;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun level = readl(&csr->resp_fill_level);
341*4882a593Smuzhiyun if (level & 0xffff) {
342*4882a593Smuzhiyun length = readl(&resp->bytes_transferred);
343*4882a593Smuzhiyun status = readl(&resp->status);
344*4882a593Smuzhiyun debug("recv %d bytes, status %08x\n", length, status);
345*4882a593Smuzhiyun *packetp = priv->rx_buf;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun return length;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun return -EAGAIN;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
altera_tse_free_pkt_msgdma(struct udevice * dev,uchar * packet,int length)353*4882a593Smuzhiyun static int altera_tse_free_pkt_msgdma(struct udevice *dev, uchar *packet,
354*4882a593Smuzhiyun int length)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
357*4882a593Smuzhiyun struct msgdma_extended_desc *desc = priv->rx_desc;
358*4882a593Smuzhiyun u32 rx_buf = virt_to_phys(priv->rx_buf);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun writel(0, &desc->read_addr_lo);
361*4882a593Smuzhiyun writel(0, &desc->read_addr_hi);
362*4882a593Smuzhiyun writel(rx_buf, &desc->write_addr_lo);
363*4882a593Smuzhiyun writel(0, &desc->write_addr_hi);
364*4882a593Smuzhiyun writel(PKTSIZE_ALIGN, &desc->len);
365*4882a593Smuzhiyun writel(0, &desc->burst_seq_num);
366*4882a593Smuzhiyun writel(MSGDMA_DESC_RX_STRIDE, &desc->stride);
367*4882a593Smuzhiyun writel(MSGDMA_DESC_CTL_RX_SINGLE, &desc->control);
368*4882a593Smuzhiyun debug("recv setup\n");
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun return 0;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
altera_tse_stop_msgdma(struct udevice * dev)373*4882a593Smuzhiyun static void altera_tse_stop_msgdma(struct udevice *dev)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun msgdma_reset(priv->sgdma_rx);
378*4882a593Smuzhiyun msgdma_reset(priv->sgdma_tx);
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
tse_mdio_read(struct mii_dev * bus,int addr,int devad,int reg)381*4882a593Smuzhiyun static int tse_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun struct altera_tse_priv *priv = bus->priv;
384*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
385*4882a593Smuzhiyun u32 value;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* set mdio address */
388*4882a593Smuzhiyun writel(addr, &mac_dev->mdio_phy1_addr);
389*4882a593Smuzhiyun /* get the data */
390*4882a593Smuzhiyun value = readl(&mac_dev->mdio_phy1[reg]);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return value & 0xffff;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
tse_mdio_write(struct mii_dev * bus,int addr,int devad,int reg,u16 val)395*4882a593Smuzhiyun static int tse_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
396*4882a593Smuzhiyun u16 val)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun struct altera_tse_priv *priv = bus->priv;
399*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /* set mdio address */
402*4882a593Smuzhiyun writel(addr, &mac_dev->mdio_phy1_addr);
403*4882a593Smuzhiyun /* set the data */
404*4882a593Smuzhiyun writel(val, &mac_dev->mdio_phy1[reg]);
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun return 0;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
tse_mdio_init(const char * name,struct altera_tse_priv * priv)409*4882a593Smuzhiyun static int tse_mdio_init(const char *name, struct altera_tse_priv *priv)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun struct mii_dev *bus = mdio_alloc();
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun if (!bus) {
414*4882a593Smuzhiyun printf("Failed to allocate MDIO bus\n");
415*4882a593Smuzhiyun return -ENOMEM;
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun bus->read = tse_mdio_read;
419*4882a593Smuzhiyun bus->write = tse_mdio_write;
420*4882a593Smuzhiyun snprintf(bus->name, sizeof(bus->name), "%s", name);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun bus->priv = (void *)priv;
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun return mdio_register(bus);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
tse_phy_init(struct altera_tse_priv * priv,void * dev)427*4882a593Smuzhiyun static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun struct phy_device *phydev;
430*4882a593Smuzhiyun unsigned int mask = 0xffffffff;
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun if (priv->phyaddr)
433*4882a593Smuzhiyun mask = 1 << priv->phyaddr;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
436*4882a593Smuzhiyun if (!phydev)
437*4882a593Smuzhiyun return -ENODEV;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun phy_connect_dev(phydev, dev);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun phydev->supported &= PHY_GBIT_FEATURES;
442*4882a593Smuzhiyun phydev->advertising = phydev->supported;
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun priv->phydev = phydev;
445*4882a593Smuzhiyun phy_config(phydev);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun return 0;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun
altera_tse_write_hwaddr(struct udevice * dev)450*4882a593Smuzhiyun static int altera_tse_write_hwaddr(struct udevice *dev)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
453*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
454*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
455*4882a593Smuzhiyun u8 *hwaddr = pdata->enetaddr;
456*4882a593Smuzhiyun u32 mac_lo, mac_hi;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun mac_lo = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
459*4882a593Smuzhiyun (hwaddr[1] << 8) | hwaddr[0];
460*4882a593Smuzhiyun mac_hi = (hwaddr[5] << 8) | hwaddr[4];
461*4882a593Smuzhiyun debug("Set MAC address to 0x%04x%08x\n", mac_hi, mac_lo);
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun writel(mac_lo, &mac_dev->mac_addr_0);
464*4882a593Smuzhiyun writel(mac_hi, &mac_dev->mac_addr_1);
465*4882a593Smuzhiyun writel(mac_lo, &mac_dev->supp_mac_addr_0_0);
466*4882a593Smuzhiyun writel(mac_hi, &mac_dev->supp_mac_addr_0_1);
467*4882a593Smuzhiyun writel(mac_lo, &mac_dev->supp_mac_addr_1_0);
468*4882a593Smuzhiyun writel(mac_hi, &mac_dev->supp_mac_addr_1_1);
469*4882a593Smuzhiyun writel(mac_lo, &mac_dev->supp_mac_addr_2_0);
470*4882a593Smuzhiyun writel(mac_hi, &mac_dev->supp_mac_addr_2_1);
471*4882a593Smuzhiyun writel(mac_lo, &mac_dev->supp_mac_addr_3_0);
472*4882a593Smuzhiyun writel(mac_hi, &mac_dev->supp_mac_addr_3_1);
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun return 0;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
altera_tse_send(struct udevice * dev,void * packet,int length)477*4882a593Smuzhiyun static int altera_tse_send(struct udevice *dev, void *packet, int length)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
480*4882a593Smuzhiyun unsigned long tx_buf = (unsigned long)packet;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun flush_dcache_range(tx_buf, tx_buf + length);
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun return priv->ops->send(dev, packet, length);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
altera_tse_recv(struct udevice * dev,int flags,uchar ** packetp)487*4882a593Smuzhiyun static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun return priv->ops->recv(dev, flags, packetp);
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
altera_tse_free_pkt(struct udevice * dev,uchar * packet,int length)494*4882a593Smuzhiyun static int altera_tse_free_pkt(struct udevice *dev, uchar *packet,
495*4882a593Smuzhiyun int length)
496*4882a593Smuzhiyun {
497*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
498*4882a593Smuzhiyun unsigned long rx_buf = (unsigned long)priv->rx_buf;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun return priv->ops->free_pkt(dev, packet, length);
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
altera_tse_stop(struct udevice * dev)505*4882a593Smuzhiyun static void altera_tse_stop(struct udevice *dev)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun priv->ops->stop(dev);
510*4882a593Smuzhiyun altera_tse_stop_mac(priv);
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
altera_tse_start(struct udevice * dev)513*4882a593Smuzhiyun static int altera_tse_start(struct udevice *dev)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
516*4882a593Smuzhiyun struct alt_tse_mac *mac_dev = priv->mac_dev;
517*4882a593Smuzhiyun u32 val;
518*4882a593Smuzhiyun int ret;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /* need to create sgdma */
521*4882a593Smuzhiyun debug("Configuring rx desc\n");
522*4882a593Smuzhiyun altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN);
523*4882a593Smuzhiyun /* start TSE */
524*4882a593Smuzhiyun debug("Configuring TSE Mac\n");
525*4882a593Smuzhiyun /* Initialize MAC registers */
526*4882a593Smuzhiyun writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length);
527*4882a593Smuzhiyun writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold);
528*4882a593Smuzhiyun writel(0, &mac_dev->rx_sel_full_threshold);
529*4882a593Smuzhiyun writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold);
530*4882a593Smuzhiyun writel(0, &mac_dev->tx_sel_full_threshold);
531*4882a593Smuzhiyun writel(8, &mac_dev->rx_almost_empty_threshold);
532*4882a593Smuzhiyun writel(8, &mac_dev->rx_almost_full_threshold);
533*4882a593Smuzhiyun writel(8, &mac_dev->tx_almost_empty_threshold);
534*4882a593Smuzhiyun writel(3, &mac_dev->tx_almost_full_threshold);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun /* NO Shift */
537*4882a593Smuzhiyun writel(0, &mac_dev->rx_cmd_stat);
538*4882a593Smuzhiyun writel(0, &mac_dev->tx_cmd_stat);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* enable MAC */
541*4882a593Smuzhiyun val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK;
542*4882a593Smuzhiyun writel(val, &mac_dev->command_config);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun /* Start up the PHY */
545*4882a593Smuzhiyun ret = phy_startup(priv->phydev);
546*4882a593Smuzhiyun if (ret) {
547*4882a593Smuzhiyun debug("Could not initialize PHY %s\n",
548*4882a593Smuzhiyun priv->phydev->dev->name);
549*4882a593Smuzhiyun return ret;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun tse_adjust_link(priv, priv->phydev);
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun if (!priv->phydev->link)
555*4882a593Smuzhiyun return -EIO;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun return 0;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun static const struct tse_ops tse_sgdma_ops = {
561*4882a593Smuzhiyun .send = altera_tse_send_sgdma,
562*4882a593Smuzhiyun .recv = altera_tse_recv_sgdma,
563*4882a593Smuzhiyun .free_pkt = altera_tse_free_pkt_sgdma,
564*4882a593Smuzhiyun .stop = altera_tse_stop_sgdma,
565*4882a593Smuzhiyun };
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun static const struct tse_ops tse_msgdma_ops = {
568*4882a593Smuzhiyun .send = altera_tse_send_msgdma,
569*4882a593Smuzhiyun .recv = altera_tse_recv_msgdma,
570*4882a593Smuzhiyun .free_pkt = altera_tse_free_pkt_msgdma,
571*4882a593Smuzhiyun .stop = altera_tse_stop_msgdma,
572*4882a593Smuzhiyun };
573*4882a593Smuzhiyun
altera_tse_probe(struct udevice * dev)574*4882a593Smuzhiyun static int altera_tse_probe(struct udevice *dev)
575*4882a593Smuzhiyun {
576*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
577*4882a593Smuzhiyun struct altera_tse_priv *priv = dev_get_priv(dev);
578*4882a593Smuzhiyun void *blob = (void *)gd->fdt_blob;
579*4882a593Smuzhiyun int node = dev_of_offset(dev);
580*4882a593Smuzhiyun const char *list, *end;
581*4882a593Smuzhiyun const fdt32_t *cell;
582*4882a593Smuzhiyun void *base, *desc_mem = NULL;
583*4882a593Smuzhiyun unsigned long addr, size;
584*4882a593Smuzhiyun int parent, addrc, sizec;
585*4882a593Smuzhiyun int len, idx;
586*4882a593Smuzhiyun int ret;
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun priv->dma_type = dev_get_driver_data(dev);
589*4882a593Smuzhiyun if (priv->dma_type == ALT_SGDMA)
590*4882a593Smuzhiyun priv->ops = &tse_sgdma_ops;
591*4882a593Smuzhiyun else
592*4882a593Smuzhiyun priv->ops = &tse_msgdma_ops;
593*4882a593Smuzhiyun /*
594*4882a593Smuzhiyun * decode regs. there are multiple reg tuples, and they need to
595*4882a593Smuzhiyun * match with reg-names.
596*4882a593Smuzhiyun */
597*4882a593Smuzhiyun parent = fdt_parent_offset(blob, node);
598*4882a593Smuzhiyun fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
599*4882a593Smuzhiyun list = fdt_getprop(blob, node, "reg-names", &len);
600*4882a593Smuzhiyun if (!list)
601*4882a593Smuzhiyun return -ENOENT;
602*4882a593Smuzhiyun end = list + len;
603*4882a593Smuzhiyun cell = fdt_getprop(blob, node, "reg", &len);
604*4882a593Smuzhiyun if (!cell)
605*4882a593Smuzhiyun return -ENOENT;
606*4882a593Smuzhiyun idx = 0;
607*4882a593Smuzhiyun while (list < end) {
608*4882a593Smuzhiyun addr = fdt_translate_address((void *)blob,
609*4882a593Smuzhiyun node, cell + idx);
610*4882a593Smuzhiyun size = fdt_addr_to_cpu(cell[idx + addrc]);
611*4882a593Smuzhiyun base = map_physmem(addr, size, MAP_NOCACHE);
612*4882a593Smuzhiyun len = strlen(list);
613*4882a593Smuzhiyun if (strcmp(list, "control_port") == 0)
614*4882a593Smuzhiyun priv->mac_dev = base;
615*4882a593Smuzhiyun else if (strcmp(list, "rx_csr") == 0)
616*4882a593Smuzhiyun priv->sgdma_rx = base;
617*4882a593Smuzhiyun else if (strcmp(list, "rx_desc") == 0)
618*4882a593Smuzhiyun priv->rx_desc = base;
619*4882a593Smuzhiyun else if (strcmp(list, "rx_resp") == 0)
620*4882a593Smuzhiyun priv->rx_resp = base;
621*4882a593Smuzhiyun else if (strcmp(list, "tx_csr") == 0)
622*4882a593Smuzhiyun priv->sgdma_tx = base;
623*4882a593Smuzhiyun else if (strcmp(list, "tx_desc") == 0)
624*4882a593Smuzhiyun priv->tx_desc = base;
625*4882a593Smuzhiyun else if (strcmp(list, "s1") == 0)
626*4882a593Smuzhiyun desc_mem = base;
627*4882a593Smuzhiyun idx += addrc + sizec;
628*4882a593Smuzhiyun list += (len + 1);
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun /* decode fifo depth */
631*4882a593Smuzhiyun priv->rx_fifo_depth = fdtdec_get_int(blob, node,
632*4882a593Smuzhiyun "rx-fifo-depth", 0);
633*4882a593Smuzhiyun priv->tx_fifo_depth = fdtdec_get_int(blob, node,
634*4882a593Smuzhiyun "tx-fifo-depth", 0);
635*4882a593Smuzhiyun /* decode phy */
636*4882a593Smuzhiyun addr = fdtdec_get_int(blob, node,
637*4882a593Smuzhiyun "phy-handle", 0);
638*4882a593Smuzhiyun addr = fdt_node_offset_by_phandle(blob, addr);
639*4882a593Smuzhiyun priv->phyaddr = fdtdec_get_int(blob, addr,
640*4882a593Smuzhiyun "reg", 0);
641*4882a593Smuzhiyun /* init desc */
642*4882a593Smuzhiyun if (priv->dma_type == ALT_SGDMA) {
643*4882a593Smuzhiyun len = sizeof(struct alt_sgdma_descriptor) * 4;
644*4882a593Smuzhiyun if (!desc_mem) {
645*4882a593Smuzhiyun desc_mem = dma_alloc_coherent(len, &addr);
646*4882a593Smuzhiyun if (!desc_mem)
647*4882a593Smuzhiyun return -ENOMEM;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun memset(desc_mem, 0, len);
650*4882a593Smuzhiyun priv->tx_desc = desc_mem;
651*4882a593Smuzhiyun priv->rx_desc = priv->tx_desc +
652*4882a593Smuzhiyun 2 * sizeof(struct alt_sgdma_descriptor);
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun /* allocate recv packet buffer */
655*4882a593Smuzhiyun priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);
656*4882a593Smuzhiyun if (!priv->rx_buf)
657*4882a593Smuzhiyun return -ENOMEM;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /* stop controller */
660*4882a593Smuzhiyun debug("Reset TSE & SGDMAs\n");
661*4882a593Smuzhiyun altera_tse_stop(dev);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun /* start the phy */
664*4882a593Smuzhiyun priv->interface = pdata->phy_interface;
665*4882a593Smuzhiyun tse_mdio_init(dev->name, priv);
666*4882a593Smuzhiyun priv->bus = miiphy_get_dev_by_name(dev->name);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun ret = tse_phy_init(priv, dev);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun return ret;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun
altera_tse_ofdata_to_platdata(struct udevice * dev)673*4882a593Smuzhiyun static int altera_tse_ofdata_to_platdata(struct udevice *dev)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun struct eth_pdata *pdata = dev_get_platdata(dev);
676*4882a593Smuzhiyun const char *phy_mode;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun pdata->phy_interface = -1;
679*4882a593Smuzhiyun phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
680*4882a593Smuzhiyun NULL);
681*4882a593Smuzhiyun if (phy_mode)
682*4882a593Smuzhiyun pdata->phy_interface = phy_get_interface_by_name(phy_mode);
683*4882a593Smuzhiyun if (pdata->phy_interface == -1) {
684*4882a593Smuzhiyun debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
685*4882a593Smuzhiyun return -EINVAL;
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun return 0;
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun static const struct eth_ops altera_tse_ops = {
692*4882a593Smuzhiyun .start = altera_tse_start,
693*4882a593Smuzhiyun .send = altera_tse_send,
694*4882a593Smuzhiyun .recv = altera_tse_recv,
695*4882a593Smuzhiyun .free_pkt = altera_tse_free_pkt,
696*4882a593Smuzhiyun .stop = altera_tse_stop,
697*4882a593Smuzhiyun .write_hwaddr = altera_tse_write_hwaddr,
698*4882a593Smuzhiyun };
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun static const struct udevice_id altera_tse_ids[] = {
701*4882a593Smuzhiyun { .compatible = "altr,tse-msgdma-1.0", .data = ALT_MSGDMA },
702*4882a593Smuzhiyun { .compatible = "altr,tse-1.0", .data = ALT_SGDMA },
703*4882a593Smuzhiyun {}
704*4882a593Smuzhiyun };
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun U_BOOT_DRIVER(altera_tse) = {
707*4882a593Smuzhiyun .name = "altera_tse",
708*4882a593Smuzhiyun .id = UCLASS_ETH,
709*4882a593Smuzhiyun .of_match = altera_tse_ids,
710*4882a593Smuzhiyun .ops = &altera_tse_ops,
711*4882a593Smuzhiyun .ofdata_to_platdata = altera_tse_ofdata_to_platdata,
712*4882a593Smuzhiyun .platdata_auto_alloc_size = sizeof(struct eth_pdata),
713*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct altera_tse_priv),
714*4882a593Smuzhiyun .probe = altera_tse_probe,
715*4882a593Smuzhiyun };
716