• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * SBE 2T3E3 synchronous serial card driver for Linux
3  *
4  * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License
8  * as published by the Free Software Foundation.
9  *
10  * This code is based on a driver written by SBE Inc.
11  */
12 
13 #include <linux/interrupt.h>
14 #include <linux/netdevice.h>
15 #include "2t3e3.h"
16 
t3e3_init(struct channel * sc)17 void t3e3_init(struct channel *sc)
18 {
19 	cpld_init(sc);
20 	dc_reset(sc);
21 	dc_init(sc);
22 	exar7250_init(sc);
23 	exar7300_init(sc);
24 }
25 
t3e3_if_start_xmit(struct sk_buff * skb,struct net_device * dev)26 int t3e3_if_start_xmit(struct sk_buff *skb, struct net_device *dev)
27 {
28 	struct channel *sc = dev_to_priv(dev);
29 	u32 current_write, last_write;
30 	unsigned long flags;
31 	struct sk_buff *skb2;
32 
33 	if (skb == NULL) {
34 		sc->s.out_errors++;
35 		return 0;
36 	}
37 
38 	if (sc->p.transmitter_on != SBE_2T3E3_ON) {
39 		sc->s.out_errors++;
40 		sc->s.out_dropped++;
41 		dev_kfree_skb_any(skb);
42 		return 0;
43 	}
44 
45 	if (sc->s.OOF && sc->p.loopback == SBE_2T3E3_LOOPBACK_NONE) {
46 		sc->s.out_dropped++;
47 		dev_kfree_skb_any(skb);
48 		return 0;
49 	}
50 
51 	spin_lock_irqsave(&sc->ether.tx_lock, flags);
52 
53 	current_write = sc->ether.tx_ring_current_write;
54 	for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
55 		if (skb2->len) {
56 			if ((sc->ether.tx_ring[current_write].tdes1 &
57 			     SBE_2T3E3_TX_DESC_BUFFER_1_SIZE) > 0)
58 				break;
59 			current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
60 			/*
61 			 * Leave at least 1 tx desc free so that dc_intr_tx() can
62 			 * identify empty list
63 			 */
64 			if (current_write == sc->ether.tx_ring_current_read)
65 				break;
66 		}
67 	}
68 	if (skb2 != NULL) {
69 		netif_stop_queue(sc->dev);
70 		sc->ether.tx_full = 1;
71 		dev_dbg(&sc->pdev->dev, "SBE 2T3E3: out of descriptors\n");
72 		spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
73 		return NETDEV_TX_BUSY;
74 	}
75 
76 	current_write = last_write = sc->ether.tx_ring_current_write;
77 	dev_dbg(&sc->pdev->dev, "sending mbuf (current_write = %d)\n",
78 		current_write);
79 
80 	for (skb2 = skb; skb2 != NULL; skb2 = NULL) {
81 		if (skb2->len) {
82 			dev_dbg(&sc->pdev->dev,
83 				"sending mbuf (len = %d, next = %p)\n",
84 				skb2->len, NULL);
85 
86 			sc->ether.tx_free_cnt--;
87 			sc->ether.tx_ring[current_write].tdes0 = 0;
88 			sc->ether.tx_ring[current_write].tdes1 &=
89 				SBE_2T3E3_TX_DESC_END_OF_RING |
90 				SBE_2T3E3_TX_DESC_SECOND_ADDRESS_CHAINED;
91 /* DISABLE_PADDING sometimes gets lost somehow, hands off... */
92 			sc->ether.tx_ring[current_write].tdes1 |=
93 				SBE_2T3E3_TX_DESC_DISABLE_PADDING | skb2->len;
94 
95 			if (current_write == sc->ether.tx_ring_current_write) {
96 				sc->ether.tx_ring[current_write].tdes1 |=
97 					SBE_2T3E3_TX_DESC_FIRST_SEGMENT;
98 			} else {
99 				sc->ether.tx_ring[current_write].tdes0 =
100 					SBE_2T3E3_TX_DESC_21143_OWN;
101 			}
102 
103 			sc->ether.tx_ring[current_write].tdes2 = virt_to_phys(skb2->data);
104 			sc->ether.tx_data[current_write] = NULL;
105 
106 			last_write = current_write;
107 			current_write = (current_write + 1) % SBE_2T3E3_TX_DESC_RING_SIZE;
108 		}
109 	}
110 
111 	sc->ether.tx_data[last_write] = skb;
112 	sc->ether.tx_ring[last_write].tdes1 |=
113 		SBE_2T3E3_TX_DESC_LAST_SEGMENT |
114 		SBE_2T3E3_TX_DESC_INTERRUPT_ON_COMPLETION;
115 	sc->ether.tx_ring[sc->ether.tx_ring_current_write].tdes0 |=
116 		SBE_2T3E3_TX_DESC_21143_OWN;
117 	sc->ether.tx_ring_current_write = current_write;
118 
119 	dev_dbg(&sc->pdev->dev, "txput: tdes0 = %08X        tdes1 = %08X\n",
120 		sc->ether.tx_ring[last_write].tdes0,
121 		sc->ether.tx_ring[last_write].tdes1);
122 
123 	dc_write(sc->addr, SBE_2T3E3_21143_REG_TRANSMIT_POLL_DEMAND,
124 		 0xffffffff);
125 
126 	spin_unlock_irqrestore(&sc->ether.tx_lock, flags);
127 	return 0;
128 }
129 
130 
t3e3_read_card_serial_number(struct channel * sc)131 void t3e3_read_card_serial_number(struct channel *sc)
132 {
133 	u32 i;
134 
135 	for (i = 0; i < 3; i++)
136 		sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i);
137 
138 	printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n",
139 	       sc->ether.card_serial_number[0], sc->ether.card_serial_number[1],
140 	       sc->ether.card_serial_number[2]);
141 }
142 
143 /*
144   bit 0 led1 (green)
145   bit 1 led1 (yellow)
146 
147   bit 2 led2 (green)
148   bit 3 led2 (yellow)
149 
150   bit 4 led3 (green)
151   bit 5 led3 (yellow)
152 
153   bit 6 led4 (green)
154   bit 7 led4 (yellow)
155 */
156 
update_led(struct channel * sc,int blinker)157 void update_led(struct channel *sc, int blinker)
158 {
159 	int leds;
160 	if (sc->s.LOS)
161 		leds = 0; /* led1 = off */
162 	else if (sc->s.OOF)
163 		leds = 2; /* led1 = yellow */
164 	else if ((blinker & 1) && sc->rcv_count) {
165 		leds = 0; /* led1 = off */
166 		sc->rcv_count = 0;
167 	} else
168 		leds = 1; /* led1 = green */
169 	cpld_write(sc, SBE_2T3E3_CPLD_REG_LEDR, leds);
170 	sc->leds = leds;
171 }
172