net: ethernet: micrel: fix an error code
[linux-2.6-block.git] / drivers / net / ethernet / micrel / ks8842.c
CommitLineData
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1/*
a1aa8822 2 * ks8842.c timberdale KS8842 ethernet driver
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="18">b07878e5
R
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * The Micrel KS8842 behind the timberdale FPGA
28bd620c 21 * The genuine Micrel KS8841/42 device with ISA 16/32bit bus interface
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
22 */
23
0dc7d2b3
JP
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
a6b7a407 26#include <linux/interrupt.h>
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/platform_device.h>
30#include <linux/netdevice.h>
31#include <linux/etherdevice.h>
32#include <linux/ethtool.h>
a1aa8822 33#include <linux/ks8842.h>
94fe8c68
RR
34#include <linux/dmaengine.h>
35#include <linux/dma-mapping.h>
36#include <linux/scatterlist.h>
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
37
38#define DRV_NAME "ks8842"
39
40/* Timberdale specific Registers */
db5824dd
RR
41#define REG_TIMB_RST 0x1c
42#define REG_TIMB_FIFO 0x20
43#define REG_TIMB_ISR 0x24
44#define REG_TIMB_IER 0x28
45#define REG_TIMB_IAR 0x2C
46#define REQ_TIMB_DMA_RESUME 0x30
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="42">b07878e5
R
47
48/* KS8842 registers */
49
50#define REG_SELECT_BANK 0x0e
51
52/* bank 0 registers */
53#define REG_QRFCR 0x04
54
55/* bank 2 registers */
56#define REG_MARL 0x00
57#define REG_MARM 0x02
58#define REG_MARH 0x04
59
60/* bank 3 registers */
61#define REG_GRR 0x06
62
63/* bank 16 registers */
64#define REG_TXCR 0x00
65#define REG_TXSR 0x02
66#define REG_RXCR 0x04
67#define REG_TXMIR 0x08
68#define REG_RXMIR 0x0A
69
70/* bank 17 registers */
71#define REG_TXQCR 0x00
72#define REG_RXQCR 0x02
73#define REG_TXFDPR 0x04
74#define REG_RXFDPR 0x06
75#define REG_QMU_DATA_LO 0x08
76#define REG_QMU_DATA_HI 0x0A
77
78/* bank 18 registers */
79#define REG_IER 0x00
80#define IRQ_LINK_CHANGE 0x8000
81#define IRQ_TX 0x4000
82#define IRQ_RX 0x2000
83#define IRQ_RX_OVERRUN 0x0800
84#define IRQ_TX_STOPPED 0x0200
85#define IRQ_RX_STOPPED 0x0100
86#define IRQ_RX_ERROR 0x0080
87#define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \
88 IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
94fe8c68
RR
89/* When running via timberdale in DMA mode, the RX interrupt should be
90 enabled in the KS8842, but not in the FPGA IP, since the IP handles
91 RX DMA internally.
92 TX interrupts are not needed it is handled by the FPGA the driver is
93 notified via DMA callbacks.
94*/
95#define ENABLED_IRQS_DMA_IP (IRQ_LINK_CHANGE | IRQ_RX_STOPPED | \
96 IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
97#define ENABLED_IRQS_DMA (ENABLED_IRQS_DMA_IP | IRQ_RX)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="38">b07878e5
R
98#define REG_ISR 0x02
99#define REG_RXSR 0x04
100#define RXSR_VALID 0x8000
101#define RXSR_BROADCAST 0x80
102#define RXSR_MULTICAST 0x40
103#define RXSR_UNICAST 0x20
104#define RXSR_FRAMETYPE 0x08
105#define RXSR_TOO_LONG 0x04
106#define RXSR_RUNT 0x02
107#define RXSR_CRC_ERROR 0x01
108#define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR)
109
110/* bank 32 registers */
111#define REG_SW_ID_AND_ENABLE 0x00
112#define REG_SGCR1 0x02
113#define REG_SGCR2 0x04
114#define REG_SGCR3 0x06
115
116/* bank 39 registers */
117#define REG_MACAR1 0x00
118#define REG_MACAR2 0x02
119#define REG_MACAR3 0x04
120
121/* bank 45 registers */
122#define REG_P1MBCR 0x00
123#define REG_P1MBSR 0x02
124
125/* bank 46 registers */
126#define REG_P2MBCR 0x00
127#define REG_P2MBSR 0x02
128
129/* bank 48 registers */
130#define REG_P1CR2 0x02
131
132/* bank 49 registers */
133#define REG_P1CR4 0x02
134#define REG_P1SR 0x04
135
28bd620c
DC
136/* flags passed by platform_device for configuration */
137#define MICREL_KS884X 0x01 /* 0=Timeberdale(FPGA), 1=Micrel */
138#define KS884X_16BIT 0x02 /* 1=16bit, 0=32bit */
139
94fe8c68
RR
140#define DMA_BUFFER_SIZE 2048
141
142struct ks8842_tx_dma_ctl {
143 struct dma_chan *chan;
144 struct dma_async_tx_descriptor *adesc;
145 void *buf;
146 struct scatterlist sg;
147 int channel;
148};
149
150struct ks8842_rx_dma_ctl {
151 struct dma_chan *chan;
152 struct dma_async_tx_descriptor *adesc;
153 struct sk_buff *skb;
154 struct scatterlist sg;
155 struct tasklet_struct tasklet;
156 int channel;
157};
158
159#define KS8842_USE_DMA(adapter) (((adapter)->dma_tx.channel != -1) && \
160 ((adapter)->dma_rx.channel != -1))
161
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
162struct ks8842_adapter {
163 void __iomem *hw_addr;
164 int irq;
28bd620c 165 unsigned long conf_flags; /* copy of platform_device config */
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
166 struct tasklet_struct tasklet;
167 spinlock_t lock; /* spinlock to be interrupt safe */
cc88e450
RR
168 struct work_struct timeout_work;
169 struct net_device *netdev;
94fe8c68
RR
170 struct device *dev;
171 struct ks8842_tx_dma_ctl dma_tx;
172 struct ks8842_rx_dma_ctl dma_rx;
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
173};
174
94fe8c68
RR
175static void ks8842_dma_rx_cb(void *data);
176static void ks8842_dma_tx_cb(void *data);
177
178static inline void ks8842_resume_dma(struct ks8842_adapter *adapter)
179{
180 iowrite32(1, adapter->hw_addr + REQ_TIMB_DMA_RESUME);
181}
182
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="69">b07878e5
R
183static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank)
184{
185 iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK);
186}
187
188static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank,
189 u8 value, int offset)
190{
191 ks8842_select_bank(adapter, bank);
192 iowrite8(value, adapter->hw_addr + offset);
193}
194
195static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank,
196 u16 value, int offset)
197{
198 ks8842_select_bank(adapter, bank);
199 iowrite16(value, adapter->hw_addr + offset);
200}
201
202static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank,
203 u16 bits, int offset)
204{
205 u16 reg;
206 ks8842_select_bank(adapter, bank);
207 reg = ioread16(adapter->hw_addr + offset);
208 reg |= bits;
209 iowrite16(reg, adapter->hw_addr + offset);
210}
211
212static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank,
213 u16 bits, int offset)
214{
215 u16 reg;
216 ks8842_select_bank(adapter, bank);
217 reg = ioread16(adapter->hw_addr + offset);
218 reg &= ~bits;
219 iowrite16(reg, adapter->hw_addr + offset);
220}
221
222static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank,
223 u32 value, int offset)
224{
225 ks8842_select_bank(adapter, bank);
226 iowrite32(value, adapter->hw_addr + offset);
227}
228
229static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank,
230 int offset)
231{
232 ks8842_select_bank(adapter, bank);
233 return ioread8(adapter->hw_addr + offset);
234}
235
236static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank,
237 int offset)
238{
239 ks8842_select_bank(adapter, bank);
240 return ioread16(adapter->hw_addr + offset);
241}
242
243static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank,
244 int offset)
245{
246 ks8842_select_bank(adapter, bank);
247 return ioread32(adapter->hw_addr + offset);
248}
249
250static void ks8842_reset(struct ks8842_adapter *adapter)
251{
28bd620c
DC
252 if (adapter->conf_flags & MICREL_KS884X) {
253 ks8842_write16(adapter, 3, 1, REG_GRR);
254 msleep(10);
255 iowrite16(0, adapter->hw_addr + REG_GRR);
256 } else {
257 /* The KS8842 goes haywire when doing softare reset
258 * a work around in the timberdale IP is implemented to
259 * do a hardware reset instead
260 ks8842_write16(adapter, 3, 1, REG_GRR);
261 msleep(10);
262 iowrite16(0, adapter->hw_addr + REG_GRR);
263 */
264 iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
265 msleep(20);
266 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="57">b07878e5
R
267}
268
269static void ks8842_update_link_status(struct net_device *netdev,
270 struct ks8842_adapter *adapter)
271{
272 /* check the status of the link */
273 if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) {
274 netif_carrier_on(netdev);
275 netif_wake_queue(netdev);
276 } else {
277 netif_stop_queue(netdev);
278 netif_carrier_off(netdev);
279 }
280}
281
282static void ks8842_enable_tx(struct ks8842_adapter *adapter)
283{
284 ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR);
285}
286
287static void ks8842_disable_tx(struct ks8842_adapter *adapter)
288{
289 ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR);
290}
291
292static void ks8842_enable_rx(struct ks8842_adapter *adapter)
293{
294 ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR);
295}
296
297static void ks8842_disable_rx(struct ks8842_adapter *adapter)
298{
299 ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR);
300}
301
302static void ks8842_reset_hw(struct ks8842_adapter *adapter)
303{
304 /* reset the HW */
305 ks8842_reset(adapter);
306
307 /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */
308 ks8842_write16(adapter, 16, 0x000E, REG_TXCR);
309
310 /* enable the receiver, uni + multi + broadcast + flow ctrl
311 + crc strip */
312 ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400,
313 REG_RXCR);
314
315 /* TX frame pointer autoincrement */
316 ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR);
317
318 /* RX frame pointer autoincrement */
319 ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR);
320
321 /* RX 2 kb high watermark */
322 ks8842_write16(adapter, 0, 0x1000, REG_QRFCR);
323
25985edc 324 /* aggressive back off in half duplex */
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
325 ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1);
326
327 /* enable no excessive collison drop */
328 ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2);
329
330 /* Enable port 1 force flow control / back pressure / transmit / recv */
331 ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2);
332
333 /* restart port auto-negotiation */
334 ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
28bd620c 335
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
336 /* Enable the transmitter */
337 ks8842_enable_tx(adapter);
338
339 /* Enable the receiver */
340 ks8842_enable_rx(adapter);
341
342 /* clear all interrupts */
343 ks8842_write16(adapter, 18, 0xffff, REG_ISR);
344
345 /* enable interrupts */
94fe8c68
RR
346 if (KS8842_USE_DMA(adapter)) {
347 /* When running in DMA Mode the RX interrupt is not enabled in
348 timberdale because RX data is received by DMA callbacks
349 it must still be enabled in the KS8842 because it indicates
350 to timberdale when there is RX data for it's DMA FIFOs */
351 iowrite16(ENABLED_IRQS_DMA_IP, adapter->hw_addr + REG_TIMB_IER);
352 ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
353 } else {
354 if (!(adapter->conf_flags & MICREL_KS884X))
355 iowrite16(ENABLED_IRQS,
356 adapter->hw_addr + REG_TIMB_IER);
357 ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
358 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="12">b07878e5
R
359 /* enable the switch */
360 ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
361}
362
363static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
364{
365 int i;
366 u16 mac;
367
368 for (i = 0; i < ETH_ALEN; i++)
369 dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);
370
28bd620c
DC
371 if (adapter->conf_flags & MICREL_KS884X) {
372 /*
373 the sequence of saving mac addr between MAC and Switch is
374 different.
375 */
376
377 mac = ks8842_read16(adapter, 2, REG_MARL);
378 ks8842_write16(adapter, 39, mac, REG_MACAR3);
379 mac = ks8842_read16(adapter, 2, REG_MARM);
380 ks8842_write16(adapter, 39, mac, REG_MACAR2);
381 mac = ks8842_read16(adapter, 2, REG_MARH);
382 ks8842_write16(adapter, 39, mac, REG_MACAR1);
383 } else {
384
385 /* make sure the switch port uses the same MAC as the QMU */
386 mac = ks8842_read16(adapter, 2, REG_MARL);
387 ks8842_write16(adapter, 39, mac, REG_MACAR1);
388 mac = ks8842_read16(adapter, 2, REG_MARM);
389 ks8842_write16(adapter, 39, mac, REG_MACAR2);
390 mac = ks8842_read16(adapter, 2, REG_MARH);
391 ks8842_write16(adapter, 39, mac, REG_MACAR3);
392 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
393}
394
a1aa8822
RR
395static void ks8842_write_mac_addr(struct ks8842_adapter *adapter, u8 *mac)
396{
397 unsigned long flags;
398 unsigned i;
399
400 spin_lock_irqsave(&adapter->lock, flags);
401 for (i = 0; i < ETH_ALEN; i++) {
402 ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
28bd620c
DC
403 if (!(adapter->conf_flags & MICREL_KS884X))
404 ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
405 REG_MACAR1 + i);
406 }
407
408 if (adapter->conf_flags & MICREL_KS884X) {
409 /*
410 the sequence of saving mac addr between MAC and Switch is
411 different.
412 */
413
414 u16 mac;
415
416 mac = ks8842_read16(adapter, 2, REG_MARL);
417 ks8842_write16(adapter, 39, mac, REG_MACAR3);
418 mac = ks8842_read16(adapter, 2, REG_MARM);
419 ks8842_write16(adapter, 39, mac, REG_MACAR2);
420 mac = ks8842_read16(adapter, 2, REG_MARH);
421 ks8842_write16(adapter, 39, mac, REG_MACAR1);
a1aa8822
RR
422 }
423 spin_unlock_irqrestore(&adapter->lock, flags);
424}
425
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="5">b07878e5
R
426static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
427{
428 return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
429}
430
94fe8c68
RR
431static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev)
432{
433 struct ks8842_adapter *adapter = netdev_priv(netdev);
434 struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx;
435 u8 *buf = ctl->buf;
436
437 if (ctl->adesc) {
438 netdev_dbg(netdev, "%s: TX ongoing\n", __func__);
439 /* transfer ongoing */
440 return NETDEV_TX_BUSY;
441 }
442
443 sg_dma_len(&ctl->sg) = skb->len + sizeof(u32);
444
445 /* copy data to the TX buffer */
446 /* the control word, enable IRQ, port 1 and the length */
447 *buf++ = 0x00;
448 *buf++ = 0x01; /* Port 1 */
449 *buf++ = skb->len & 0xff;
450 *buf++ = (skb->len >> 8) & 0xff;
451 skb_copy_from_linear_data(skb, buf, skb->len);
452
453 dma_sync_single_range_for_device(adapter->dev,
454 sg_dma_address(&ctl->sg), 0, sg_dma_len(&ctl->sg),
455 DMA_TO_DEVICE);
456
457 /* make sure the length is a multiple of 4 */
458 if (sg_dma_len(&ctl->sg) % 4)
459 sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4;
460
16052827 461 ctl->adesc = dmaengine_prep_slave_sg(ctl->chan,
0776ae7b 462 &ctl->sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
94fe8c68
RR
463 if (!ctl->adesc)
464 return NETDEV_TX_BUSY;
465
466 ctl->adesc->callback_param = netdev;
467 ctl->adesc->callback = ks8842_dma_tx_cb;
468 ctl->adesc->tx_submit(ctl->adesc);
469
470 netdev->stats.tx_bytes += skb->len;
471
472 dev_kfree_skb(skb);
473
474 return NETDEV_TX_OK;
475}
476
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
477static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
478{
479 struct ks8842_adapter *adapter = netdev_priv(netdev);
480 int len = skb->len;
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 481
a99db196 482 netdev_dbg(netdev, "%s: len %u head %p data %p tail %p end %p\n",
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="7">b07878e5
R
483 __func__, skb->len, skb->head, skb->data,
484 skb_tail_pointer(skb), skb_end_pointer(skb));
485
486 /* check FIFO buffer space, we need space for CRC and command bits */
487 if (ks8842_tx_fifo_space(adapter) < len + 8)
488 return NETDEV_TX_BUSY;
489
28bd620c
DC
490 if (adapter->conf_flags & KS884X_16BIT) {
491 u16 *ptr16 = (u16 *)skb->data;
492 ks8842_write16(adapter, 17, 0x8000 | 0x100, REG_QMU_DATA_LO);
493 ks8842_write16(adapter, 17, (u16)len, REG_QMU_DATA_HI);
494 netdev->stats.tx_bytes += len;
495
496 /* copy buffer */
497 while (len > 0) {
498 iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_LO);
499 iowrite16(*ptr16++, adapter->hw_addr + REG_QMU_DATA_HI);
500 len -= sizeof(u32);
501 }
502 } else {
503
504 u32 *ptr = (u32 *)skb->data;
505 u32 ctrl;
506 /* the control word, enable IRQ, port 1 and the length */
507 ctrl = 0x8000 | 0x100 | (len << 16);
508 ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 509
28bd620c 510 netdev->stats.tx_bytes += len;
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 511
28bd620c
DC
512 /* copy buffer */
513 while (len > 0) {
514 iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
515 len -= sizeof(u32);
516 ptr++;
517 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
518 }
519
520 /* enqueue packet */
521 ks8842_write16(adapter, 17, 1, REG_TXQCR);
522
523 dev_kfree_skb(skb);
524
525 return NETDEV_TX_OK;
526}
527
94fe8c68
RR
528static void ks8842_update_rx_err_counters(struct net_device *netdev, u32 status)
529{
530 netdev_dbg(netdev, "RX error, status: %x\n", status);
531
532 netdev->stats.rx_errors++;
533 if (status & RXSR_TOO_LONG)
534 netdev->stats.rx_length_errors++;
535 if (status & RXSR_CRC_ERROR)
536 netdev->stats.rx_crc_errors++;
537 if (status & RXSR_RUNT)
538 netdev->stats.rx_frame_errors++;
539}
540
541static void ks8842_update_rx_counters(struct net_device *netdev, u32 status,
542 int len)
543{
544 netdev_dbg(netdev, "RX packet, len: %d\n", len);
545
546 netdev->stats.rx_packets++;
547 netdev->stats.rx_bytes += len;
548 if (status & RXSR_MULTICAST)
549 netdev->stats.multicast++;
550}
551
552static int __ks8842_start_new_rx_dma(struct net_device *netdev)
553{
554 struct ks8842_adapter *adapter = netdev_priv(netdev);
555 struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
556 struct scatterlist *sg = &ctl->sg;
557 int err;
558
559 ctl->skb = netdev_alloc_skb(netdev, DMA_BUFFER_SIZE);
560 if (ctl->skb) {
561 sg_init_table(sg, 1);
562 sg_dma_address(sg) = dma_map_single(adapter->dev,
563 ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
564 err = dma_mapping_error(adapter->dev, sg_dma_address(sg));
565 if (unlikely(err)) {
566 sg_dma_address(sg) = 0;
567 goto out;
568 }
569
570 sg_dma_len(sg) = DMA_BUFFER_SIZE;
571
16052827 572 ctl->adesc = dmaengine_prep_slave_sg(ctl->chan,
0776ae7b 573 sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
94fe8c68
RR
574
575 if (!ctl->adesc)
576 goto out;
577
578 ctl->adesc->callback_param = netdev;
579 ctl->adesc->callback = ks8842_dma_rx_cb;
580 ctl->adesc->tx_submit(ctl->adesc);
581 } else {
582 err = -ENOMEM;
583 sg_dma_address(sg) = 0;
584 goto out;
585 }
586
587 return err;
588out:
589 if (sg_dma_address(sg))
590 dma_unmap_single(adapter->dev, sg_dma_address(sg),
591 DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
592 sg_dma_address(sg) = 0;
593 if (ctl->skb)
594 dev_kfree_skb(ctl->skb);
595
596 ctl->skb = NULL;
597
598 printk(KERN_ERR DRV_NAME": Failed to start RX DMA: %d\n", err);
599 return err;
600}
601
602static void ks8842_rx_frame_dma_tasklet(unsigned long arg)
603{
604 struct net_device *netdev = (struct net_device *)arg;
605 struct ks8842_adapter *adapter = netdev_priv(netdev);
606 struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
607 struct sk_buff *skb = ctl->skb;
608 dma_addr_t addr = sg_dma_address(&ctl->sg);
609 u32 status;
610
611 ctl->adesc = NULL;
612
613 /* kick next transfer going */
614 __ks8842_start_new_rx_dma(netdev);
615
616 /* now handle the data we got */
617 dma_unmap_single(adapter->dev, addr, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
618
619 status = *((u32 *)skb->data);
620
621 netdev_dbg(netdev, "%s - rx_data: status: %x\n",
622 __func__, status & 0xffff);
623
624 /* check the status */
625 if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
626 int len = (status >> 16) & 0x7ff;
627
628 ks8842_update_rx_counters(netdev, status, len);
629
630 /* reserve 4 bytes which is the status word */
631 skb_reserve(skb, 4);
632 skb_put(skb, len);
633
634 skb->protocol = eth_type_trans(skb, netdev);
635 netif_rx(skb);
636 } else {
637 ks8842_update_rx_err_counters(netdev, status);
638 dev_kfree_skb(skb);
639 }
640}
641
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
642static void ks8842_rx_frame(struct net_device *netdev,
643 struct ks8842_adapter *adapter)
644{
28bd620c
DC
645 u32 status;
646 int len;
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 647
28bd620c 648 if (adapter->conf_flags & KS884X_16BIT) {
e2df8b7f
DM
649 status = ks8842_read16(adapter, 17, REG_QMU_DATA_LO);
650 len = ks8842_read16(adapter, 17, REG_QMU_DATA_HI);
28bd620c 651 netdev_dbg(netdev, "%s - rx_data: status: %x\n",
e2df8b7f 652 __func__, status);
28bd620c
DC
653 } else {
654 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
655 len = (status >> 16) & 0x7ff;
656 status &= 0xffff;
657 netdev_dbg(netdev, "%s - rx_data: status: %x\n",
658 __func__, status);
659 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
660
661 /* check the status */
662 if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
b10cec8a 663 struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len + 3);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 664
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 665 if (skb) {
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 666
94fe8c68 667 ks8842_update_rx_counters(netdev, status, len);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 668
28bd620c
DC
669 if (adapter->conf_flags & KS884X_16BIT) {
670 u16 *data16 = (u16 *)skb_put(skb, len);
671 ks8842_select_bank(adapter, 17);
672 while (len > 0) {
673 *data16++ = ioread16(adapter->hw_addr +
674 REG_QMU_DATA_LO);
675 *data16++ = ioread16(adapter->hw_addr +
676 REG_QMU_DATA_HI);
677 len -= sizeof(u32);
678 }
679 } else {
680 u32 *data = (u32 *)skb_put(skb, len);
681
682 ks8842_select_bank(adapter, 17);
683 while (len > 0) {
684 *data++ = ioread32(adapter->hw_addr +
685 REG_QMU_DATA_LO);
686 len -= sizeof(u32);
687 }
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 688 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
689 skb->protocol = eth_type_trans(skb, netdev);
690 netif_rx(skb);
691 } else
692 netdev->stats.rx_dropped++;
94fe8c68
RR
693 } else
694 ks8842_update_rx_err_counters(netdev, status);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="11">b07878e5
R
695
696 /* set high watermark to 3K */
697 ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR);
698
699 /* release the frame */
700 ks8842_write16(adapter, 17, 0x01, REG_RXQCR);
701
702 /* set high watermark to 2K */
703 ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR);
704}
705
51a700db
JH
706static void ks8842_handle_rx(struct net_device *netdev,
707 struct ks8842_adapter *adapter)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
708{
709 u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
a99db196 710 netdev_dbg(netdev, "%s Entry - rx_data: %d\n", __func__, rx_data);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
711 while (rx_data) {
712 ks8842_rx_frame(netdev, adapter);
713 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
714 }
715}
716
51a700db
JH
717static void ks8842_handle_tx(struct net_device *netdev,
718 struct ks8842_adapter *adapter)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
719{
720 u16 sr = ks8842_read16(adapter, 16, REG_TXSR);
a99db196 721 netdev_dbg(netdev, "%s - entry, sr: %x\n", __func__, sr);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="5">b07878e5
R
722 netdev->stats.tx_packets++;
723 if (netif_queue_stopped(netdev))
724 netif_wake_queue(netdev);
725}
726
51a700db 727static void ks8842_handle_rx_overrun(struct net_device *netdev,
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
728 struct ks8842_adapter *adapter)
729{
a99db196 730 netdev_dbg(netdev, "%s: entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
731 netdev->stats.rx_errors++;
732 netdev->stats.rx_fifo_errors++;
733}
734
51a700db 735static void ks8842_tasklet(unsigned long arg)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="13">b07878e5
R
736{
737 struct net_device *netdev = (struct net_device *)arg;
738 struct ks8842_adapter *adapter = netdev_priv(netdev);
739 u16 isr;
740 unsigned long flags;
741 u16 entry_bank;
742
743 /* read current bank to be able to set it back */
744 spin_lock_irqsave(&adapter->lock, flags);
745 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
746 spin_unlock_irqrestore(&adapter->lock, flags);
747
748 isr = ks8842_read16(adapter, 18, REG_ISR);
a99db196 749 netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 750
94fe8c68
RR
751 /* when running in DMA mode, do not ack RX interrupts, it is handled
752 internally by timberdale, otherwise it's DMA FIFO:s would stop
753 */
754 if (KS8842_USE_DMA(adapter))
755 isr &= ~IRQ_RX;
756
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
757 /* Ack */
758 ks8842_write16(adapter, 18, isr, REG_ISR);
759
db5824dd
RR
760 if (!(adapter->conf_flags & MICREL_KS884X))
761 /* Ack in the timberdale IP as well */
762 iowrite32(0x1, adapter->hw_addr + REG_TIMB_IAR);
763
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
764 if (!netif_running(netdev))
765 return;
766
767 if (isr & IRQ_LINK_CHANGE)
768 ks8842_update_link_status(netdev, adapter);
769
94fe8c68
RR
770 /* should not get IRQ_RX when running DMA mode */
771 if (isr & (IRQ_RX | IRQ_RX_ERROR) && !KS8842_USE_DMA(adapter))
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
772 ks8842_handle_rx(netdev, adapter);
773
94fe8c68 774 /* should only happen when in PIO mode */
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="18">b07878e5
R
775 if (isr & IRQ_TX)
776 ks8842_handle_tx(netdev, adapter);
777
778 if (isr & IRQ_RX_OVERRUN)
779 ks8842_handle_rx_overrun(netdev, adapter);
780
781 if (isr & IRQ_TX_STOPPED) {
782 ks8842_disable_tx(adapter);
783 ks8842_enable_tx(adapter);
784 }
785
786 if (isr & IRQ_RX_STOPPED) {
787 ks8842_disable_rx(adapter);
788 ks8842_enable_rx(adapter);
789 }
790
791 /* re-enable interrupts, put back the bank selection register */
792 spin_lock_irqsave(&adapter->lock, flags);
94fe8c68
RR
793 if (KS8842_USE_DMA(adapter))
794 ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
795 else
796 ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 797 iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
94fe8c68
RR
798
799 /* Make sure timberdale continues DMA operations, they are stopped while
800 we are handling the ks8842 because we might change bank */
801 if (KS8842_USE_DMA(adapter))
802 ks8842_resume_dma(adapter);
803
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="5">b07878e5
R
804 spin_unlock_irqrestore(&adapter->lock, flags);
805}
806
807static irqreturn_t ks8842_irq(int irq, void *devid)
808{
a99db196
RR
809 struct net_device *netdev = devid;
810 struct ks8842_adapter *adapter = netdev_priv(netdev);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="5">b07878e5
R
811 u16 isr;
812 u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
813 irqreturn_t ret = IRQ_NONE;
814
815 isr = ks8842_read16(adapter, 18, REG_ISR);
a99db196 816 netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
817
818 if (isr) {
94fe8c68
RR
819 if (KS8842_USE_DMA(adapter))
820 /* disable all but RX IRQ, since the FPGA relies on it*/
821 ks8842_write16(adapter, 18, IRQ_RX, REG_IER);
822 else
823 /* disable IRQ */
824 ks8842_write16(adapter, 18, 0x00, REG_IER);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="9">b07878e5
R
825
826 /* schedule tasklet */
827 tasklet_schedule(&adapter->tasklet);
828
829 ret = IRQ_HANDLED;
830 }
831
832 iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
833
94fe8c68
RR
834 /* After an interrupt, tell timberdale to continue DMA operations.
835 DMA is disabled while we are handling the ks8842 because we might
836 change bank */
837 ks8842_resume_dma(adapter);
838
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
839 return ret;
840}
841
94fe8c68
RR
842static void ks8842_dma_rx_cb(void *data)
843{
844 struct net_device *netdev = data;
845 struct ks8842_adapter *adapter = netdev_priv(netdev);
846
847 netdev_dbg(netdev, "RX DMA finished\n");
848 /* schedule tasklet */
849 if (adapter->dma_rx.adesc)
850 tasklet_schedule(&adapter->dma_rx.tasklet);
851}
852
853static void ks8842_dma_tx_cb(void *data)
854{
855 struct net_device *netdev = data;
856 struct ks8842_adapter *adapter = netdev_priv(netdev);
857 struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx;
858
859 netdev_dbg(netdev, "TX DMA finished\n");
860
861 if (!ctl->adesc)
862 return;
863
864 netdev->stats.tx_packets++;
865 ctl->adesc = NULL;
866
867 if (netif_queue_stopped(netdev))
868 netif_wake_queue(netdev);
869}
870
871static void ks8842_stop_dma(struct ks8842_adapter *adapter)
872{
873 struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
874 struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
875
876 tx_ctl->adesc = NULL;
877 if (tx_ctl->chan)
843d349c 878 dmaengine_terminate_all(tx_ctl->chan);
94fe8c68
RR
879
880 rx_ctl->adesc = NULL;
881 if (rx_ctl->chan)
843d349c 882 dmaengine_terminate_all(rx_ctl->chan);
94fe8c68
RR
883
884 if (sg_dma_address(&rx_ctl->sg))
885 dma_unmap_single(adapter->dev, sg_dma_address(&rx_ctl->sg),
886 DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
887 sg_dma_address(&rx_ctl->sg) = 0;
888
889 dev_kfree_skb(rx_ctl->skb);
890 rx_ctl->skb = NULL;
891}
892
893static void ks8842_dealloc_dma_bufs(struct ks8842_adapter *adapter)
894{
895 struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
896 struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
897
898 ks8842_stop_dma(adapter);
899
900 if (tx_ctl->chan)
901 dma_release_channel(tx_ctl->chan);
902 tx_ctl->chan = NULL;
903
904 if (rx_ctl->chan)
905 dma_release_channel(rx_ctl->chan);
906 rx_ctl->chan = NULL;
907
908 tasklet_kill(&rx_ctl->tasklet);
909
910 if (sg_dma_address(&tx_ctl->sg))
911 dma_unmap_single(adapter->dev, sg_dma_address(&tx_ctl->sg),
912 DMA_BUFFER_SIZE, DMA_TO_DEVICE);
913 sg_dma_address(&tx_ctl->sg) = 0;
914
915 kfree(tx_ctl->buf);
916 tx_ctl->buf = NULL;
917}
918
919static bool ks8842_dma_filter_fn(struct dma_chan *chan, void *filter_param)
920{
bd280635 921 return chan->chan_id == (long)filter_param;
94fe8c68
RR
922}
923
924static int ks8842_alloc_dma_bufs(struct net_device *netdev)
925{
926 struct ks8842_adapter *adapter = netdev_priv(netdev);
927 struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
928 struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
929 int err;
930
931 dma_cap_mask_t mask;
932
933 dma_cap_zero(mask);
934 dma_cap_set(DMA_SLAVE, mask);
935 dma_cap_set(DMA_PRIVATE, mask);
936
937 sg_init_table(&tx_ctl->sg, 1);
938
939 tx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn,
bd280635 940 (void *)(long)tx_ctl->channel);
94fe8c68
RR
941 if (!tx_ctl->chan) {
942 err = -ENODEV;
943 goto err;
944 }
945
946 /* allocate DMA buffer */
947 tx_ctl->buf = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
948 if (!tx_ctl->buf) {
949 err = -ENOMEM;
950 goto err;
951 }
952
953 sg_dma_address(&tx_ctl->sg) = dma_map_single(adapter->dev,
954 tx_ctl->buf, DMA_BUFFER_SIZE, DMA_TO_DEVICE);
2902bc66
DC
955 if (dma_mapping_error(adapter->dev, sg_dma_address(&tx_ctl->sg))) {
956 err = -ENOMEM;
94fe8c68
RR
957 sg_dma_address(&tx_ctl->sg) = 0;
958 goto err;
959 }
960
961 rx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn,
bd280635 962 (void *)(long)rx_ctl->channel);
94fe8c68
RR
963 if (!rx_ctl->chan) {
964 err = -ENODEV;
965 goto err;
966 }
967
968 tasklet_init(&rx_ctl->tasklet, ks8842_rx_frame_dma_tasklet,
969 (unsigned long)netdev);
970
971 return 0;
972err:
973 ks8842_dealloc_dma_bufs(adapter);
974 return err;
975}
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="8">b07878e5
R
976
977/* Netdevice operations */
978
979static int ks8842_open(struct net_device *netdev)
980{
981 struct ks8842_adapter *adapter = netdev_priv(netdev);
982 int err;
983
a99db196 984 netdev_dbg(netdev, "%s - entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 985
94fe8c68
RR
986 if (KS8842_USE_DMA(adapter)) {
987 err = ks8842_alloc_dma_bufs(netdev);
988
989 if (!err) {
990 /* start RX dma */
991 err = __ks8842_start_new_rx_dma(netdev);
992 if (err)
993 ks8842_dealloc_dma_bufs(adapter);
994 }
995
996 if (err) {
997 printk(KERN_WARNING DRV_NAME
998 ": Failed to initiate DMA, running PIO\n");
999 ks8842_dealloc_dma_bufs(adapter);
1000 adapter->dma_rx.channel = -1;
1001 adapter->dma_tx.channel = -1;
1002 }
1003 }
1004
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
1005 /* reset the HW */
1006 ks8842_reset_hw(adapter);
1007
a1aa8822
RR
1008 ks8842_write_mac_addr(adapter, netdev->dev_addr);
1009
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
1010 ks8842_update_link_status(netdev, adapter);
1011
1012 err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME,
a99db196 1013 netdev);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1014 if (err) {
0dc7d2b3 1015 pr_err("Failed to request IRQ: %d: %d\n", adapter->irq, err);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
1016 return err;
1017 }
1018
1019 return 0;
1020}
1021
1022static int ks8842_close(struct net_device *netdev)
1023{
1024 struct ks8842_adapter *adapter = netdev_priv(netdev);
1025
a99db196 1026 netdev_dbg(netdev, "%s - entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1027
cc88e450
RR
1028 cancel_work_sync(&adapter->timeout_work);
1029
94fe8c68
RR
1030 if (KS8842_USE_DMA(adapter))
1031 ks8842_dealloc_dma_bufs(adapter);
1032
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1033 /* free the irq */
a99db196 1034 free_irq(adapter->irq, netdev);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="7">b07878e5
R
1035
1036 /* disable the switch */
1037 ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE);
1038
1039 return 0;
1040}
1041
61357325
SH
1042static netdev_tx_t ks8842_xmit_frame(struct sk_buff *skb,
1043 struct net_device *netdev)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
1044{
1045 int ret;
1046 struct ks8842_adapter *adapter = netdev_priv(netdev);
1047
a99db196 1048 netdev_dbg(netdev, "%s: entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1049
94fe8c68
RR
1050 if (KS8842_USE_DMA(adapter)) {
1051 unsigned long flags;
1052 ret = ks8842_tx_frame_dma(skb, netdev);
1053 /* for now only allow one transfer at the time */
1054 spin_lock_irqsave(&adapter->lock, flags);
1055 if (adapter->dma_tx.adesc)
1056 netif_stop_queue(netdev);
1057 spin_unlock_irqrestore(&adapter->lock, flags);
1058 return ret;
1059 }
1060
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="11">b07878e5
R
1061 ret = ks8842_tx_frame(skb, netdev);
1062
1063 if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8)
1064 netif_stop_queue(netdev);
1065
1066 return ret;
1067}
1068
1069static int ks8842_set_mac(struct net_device *netdev, void *p)
1070{
1071 struct ks8842_adapter *adapter = netdev_priv(netdev);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1072 struct sockaddr *addr = p;
1073 char *mac = (u8 *)addr->sa_data;
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1074
a99db196 1075 netdev_dbg(netdev, "%s: entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
1076
1077 if (!is_valid_ether_addr(addr->sa_data))
1078 return -EADDRNOTAVAIL;
1079
1080 memcpy(netdev->dev_addr, mac, netdev->addr_len);
1081
a1aa8822 1082 ks8842_write_mac_addr(adapter, mac);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
1083 return 0;
1084}
1085
cc88e450 1086static void ks8842_tx_timeout_work(struct work_struct *work)
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1087{
cc88e450
RR
1088 struct ks8842_adapter *adapter =
1089 container_of(work, struct ks8842_adapter, timeout_work);
1090 struct net_device *netdev = adapter->netdev;
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1091 unsigned long flags;
1092
a99db196 1093 netdev_dbg(netdev, "%s: entry\n", __func__);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1094
1095 spin_lock_irqsave(&adapter->lock, flags);
94fe8c68
RR
1096
1097 if (KS8842_USE_DMA(adapter))
1098 ks8842_stop_dma(adapter);
1099
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
1100 /* disable interrupts */
1101 ks8842_write16(adapter, 18, 0, REG_IER);
1102 ks8842_write16(adapter, 18, 0xFFFF, REG_ISR);
cc88e450
RR
1103
1104 netif_stop_queue(netdev);
1105
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="4">b07878e5
R
1106 spin_unlock_irqrestore(&adapter->lock, flags);
1107
1108 ks8842_reset_hw(adapter);
1109
a1aa8822
RR
1110 ks8842_write_mac_addr(adapter, netdev->dev_addr);
1111
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1112 ks8842_update_link_status(netdev, adapter);
94fe8c68
RR
1113
1114 if (KS8842_USE_DMA(adapter))
1115 __ks8842_start_new_rx_dma(netdev);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1116}
1117
cc88e450
RR
1118static void ks8842_tx_timeout(struct net_device *netdev)
1119{
1120 struct ks8842_adapter *adapter = netdev_priv(netdev);
1121
1122 netdev_dbg(netdev, "%s: entry\n", __func__);
1123
1124 schedule_work(&adapter->timeout_work);
1125}
1126
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="9">b07878e5
R
1127static const struct net_device_ops ks8842_netdev_ops = {
1128 .ndo_open = ks8842_open,
1129 .ndo_stop = ks8842_close,
1130 .ndo_start_xmit = ks8842_xmit_frame,
1131 .ndo_set_mac_address = ks8842_set_mac,
1132 .ndo_tx_timeout = ks8842_tx_timeout,
1133 .ndo_validate_addr = eth_validate_addr
1134};
1135
0fc0b732 1136static const struct ethtool_ops ks8842_ethtool_ops = {
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="3">b07878e5
R
1137 .get_link = ethtool_op_get_link,
1138};
1139
654b8c5c 1140static int ks8842_probe(struct platform_device *pdev)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="5">b07878e5
R
1141{
1142 int err = -ENOMEM;
1143 struct resource *iomem;
1144 struct net_device *netdev;
1145 struct ks8842_adapter *adapter;
0dd14b67 1146 struct ks8842_platform_data *pdata = dev_get_platdata(&pdev->dev);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1147 u16 id;
a1aa8822 1148 unsigned i;
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="12">b07878e5
R
1149
1150 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1151 if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
1152 goto err_mem_region;
1153
1154 netdev = alloc_etherdev(sizeof(struct ks8842_adapter));
1155 if (!netdev)
1156 goto err_alloc_etherdev;
1157
1158 SET_NETDEV_DEV(netdev, &pdev->dev);
1159
1160 adapter = netdev_priv(netdev);
cc88e450
RR
1161 adapter->netdev = netdev;
1162 INIT_WORK(&adapter->timeout_work, ks8842_tx_timeout_work);
\9aöjfors, 2009-06-04 03:35:55 +0000">b07878e5 1163 adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
28bd620c
DC
1164 adapter->conf_flags = iomem->flags;
1165
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="9">b07878e5
R
1166 if (!adapter->hw_addr)
1167 goto err_ioremap;
1168
1169 adapter->irq = platform_get_irq(pdev, 0);
1170 if (adapter->irq < 0) {
1171 err = adapter->irq;
1172 goto err_get_irq;
1173 }
1174
94fe8c68
RR
1175 adapter->dev = (pdev->dev.parent) ? pdev->dev.parent : &pdev->dev;
1176
1177 /* DMA is only supported when accessed via timberdale */
1178 if (!(adapter->conf_flags & MICREL_KS884X) && pdata &&
1179 (pdata->tx_dma_channel != -1) &&
1180 (pdata->rx_dma_channel != -1)) {
1181 adapter->dma_rx.channel = pdata->rx_dma_channel;
1182 adapter->dma_tx.channel = pdata->tx_dma_channel;
1183 } else {
1184 adapter->dma_rx.channel = -1;
1185 adapter->dma_tx.channel = -1;
1186 }
1187
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
1188 tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
1189 spin_lock_init(&adapter->lock);
1190
1191 netdev->netdev_ops = &ks8842_netdev_ops;
1192 netdev->ethtool_ops = &ks8842_ethtool_ops;
1193
a1aa8822
RR
1194 /* Check if a mac address was given */
1195 i = netdev->addr_len;
1196 if (pdata) {
1197 for (i = 0; i < netdev->addr_len; i++)
1198 if (pdata->macaddr[i] != 0)
1199 break;
1200
1201 if (i < netdev->addr_len)
1202 /* an address was passed, use it */
1203 memcpy(netdev->dev_addr, pdata->macaddr,
1204 netdev->addr_len);
1205 }
1206
1207 if (i == netdev->addr_len) {
1208 ks8842_read_mac_addr(adapter, netdev->dev_addr);
1209
1210 if (!is_valid_ether_addr(netdev->dev_addr))
7ce5d222 1211 eth_hw_addr_random(netdev);
a1aa8822 1212 }
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
1213
1214 id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
1215
1216 strcpy(netdev->name, "eth%d");
1217 err = register_netdev(netdev);
1218 if (err)
1219 goto err_register;
1220
1221 platform_set_drvdata(pdev, netdev);
1222
0dc7d2b3 1223 pr_info("Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="15">b07878e5
R
1224 (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
1225
1226 return 0;
1227
1228err_register:
1229err_get_irq:
1230 iounmap(adapter->hw_addr);
1231err_ioremap:
1232 free_netdev(netdev);
1233err_alloc_etherdev:
1234 release_mem_region(iomem->start, resource_size(iomem));
1235err_mem_region:
1236 return err;
1237}
1238
654b8c5c 1239static int ks8842_remove(struct platform_device *pdev)
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="10">b07878e5
R
1240{
1241 struct net_device *netdev = platform_get_drvdata(pdev);
1242 struct ks8842_adapter *adapter = netdev_priv(netdev);
1243 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1244
1245 unregister_netdev(netdev);
1246 tasklet_kill(&adapter->tasklet);
1247 iounmap(adapter->hw_addr);
1248 free_netdev(netdev);
1249 release_mem_region(iomem->start, resource_size(iomem));
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="7">b07878e5
R
1250 return 0;
1251}
1252
1253
1254static struct platform_driver ks8842_platform_driver = {
1255 .driver = {
1256 .name = DRV_NAME,
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1257 },
1258 .probe = ks8842_probe,
654b8c5c 1259 .remove = ks8842_remove,
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="2">b07878e5
R
1260};
1261
db62f684 1262module_platform_driver(ks8842_platform_driver);
\9aöjfors, 2009-06-04 03:35:55 +0000" rowspan="6">b07878e5
R
1263
1264MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver");
1265MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
1266MODULE_LICENSE("GPL v2");
1267MODULE_ALIAS("platform:ks8842");
1268