Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
isdn
hysdn
hysdn_net.c
Go to the documentation of this file.
1
/* $Id: hysdn_net.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
2
*
3
* Linux driver for HYSDN cards, net (ethernet type) handling routines.
4
*
5
* Author Werner Cornelius (
[email protected]
) for Hypercope GmbH
6
* Copyright 1999 by Werner Cornelius (
[email protected]
)
7
*
8
* This software may be used and distributed according to the terms
9
* of the GNU General Public License, incorporated herein by reference.
10
*
11
* This net module has been inspired by the skeleton driver from
12
* Donald Becker (
[email protected]
)
13
*
14
*/
15
16
#include <linux/module.h>
17
#include <linux/signal.h>
18
#include <linux/kernel.h>
19
#include <linux/netdevice.h>
20
#include <
linux/etherdevice.h
>
21
#include <
linux/skbuff.h
>
22
#include <
linux/inetdevice.h
>
23
24
#include "
hysdn_defs.h
"
25
26
unsigned
int
hynet_enable
= 0xffffffff;
27
module_param
(
hynet_enable
,
uint
, 0);
28
29
#define MAX_SKB_BUFFERS 20
/* number of buffers for keeping TX-data */
30
31
/****************************************************************************/
32
/* structure containing the complete network data. The structure is aligned */
33
/* in a way that both, the device and statistics are kept inside it. */
34
/* for proper access, the device structure MUST be the first var/struct */
35
/* inside the definition. */
36
/****************************************************************************/
37
struct
net_local
{
38
/* Tx control lock. This protects the transmit buffer ring
39
* state along with the "tx full" state of the driver. This
40
* means all netif_queue flow control actions are protected
41
* by this lock as well.
42
*/
43
struct
net_device
*
dev
;
44
spinlock_t
lock
;
45
struct
sk_buff
*
skbs
[
MAX_SKB_BUFFERS
];
/* pointers to tx-skbs */
46
int
in_idx
,
out_idx
;
/* indexes to buffer ring */
47
int
sk_count
;
/* number of buffers currently in ring */
48
};
/* net_local */
49
50
51
52
/*********************************************************************/
53
/* Open/initialize the board. This is called (in the current kernel) */
54
/* sometime after booting when the 'ifconfig' program is run. */
55
/* This routine should set everything up anew at each open, even */
56
/* registers that "should" only need to be set once at boot, so that */
57
/* there is non-reboot way to recover if something goes wrong. */
58
/*********************************************************************/
59
static
int
60
net_open(
struct
net_device
*
dev
)
61
{
62
struct
in_device *in_dev;
63
hysdn_card
*
card
= dev->
ml_priv
;
64
int
i
;
65
66
netif_start_queue(dev);
/* start tx-queueing */
67
68
/* Fill in the MAC-level header (if not already set) */
69
if
(!card->
mac_addr
[0]) {
70
for
(i = 0; i <
ETH_ALEN
; i++)
71
dev->
dev_addr
[i] = 0xfc;
72
if
((in_dev = dev->
ip_ptr
) !=
NULL
) {
73
struct
in_ifaddr *ifa = in_dev->ifa_list;
74
if
(ifa !=
NULL
)
75
memcpy
(dev->
dev_addr
+ (ETH_ALEN -
sizeof
(ifa->ifa_local)), &ifa->ifa_local,
sizeof
(ifa->ifa_local));
76
}
77
}
else
78
memcpy
(dev->
dev_addr
, card->
mac_addr
,
ETH_ALEN
);
79
80
return
(0);
81
}
/* net_open */
82
83
/*******************************************/
84
/* flush the currently occupied tx-buffers */
85
/* must only be called when device closed */
86
/*******************************************/
87
static
void
88
flush_tx_buffers(
struct
net_local
*nl)
89
{
90
91
while
(nl->
sk_count
) {
92
dev_kfree_skb(nl->
skbs
[nl->
out_idx
++]);
/* free skb */
93
if
(nl->
out_idx
>=
MAX_SKB_BUFFERS
)
94
nl->
out_idx
= 0;
/* wrap around */
95
nl->
sk_count
--;
96
}
97
}
/* flush_tx_buffers */
98
99
100
/*********************************************************************/
101
/* close/decativate the device. The device is not removed, but only */
102
/* deactivated. */
103
/*********************************************************************/
104
static
int
105
net_close(
struct
net_device
*dev)
106
{
107
108
netif_stop_queue(dev);
/* disable queueing */
109
110
flush_tx_buffers((
struct
net_local
*) dev);
111
112
return
(0);
/* success */
113
}
/* net_close */
114
115
/************************************/
116
/* send a packet on this interface. */
117
/* new style for kernel >= 2.3.33 */
118
/************************************/
119
static
netdev_tx_t
120
net_send_packet(
struct
sk_buff
*
skb
,
struct
net_device
*dev)
121
{
122
struct
net_local
*
lp
= (
struct
net_local
*) dev;
123
124
spin_lock_irq(&lp->
lock
);
125
126
lp->
skbs
[lp->
in_idx
++] =
skb
;
/* add to buffer list */
127
if
(lp->
in_idx
>=
MAX_SKB_BUFFERS
)
128
lp->
in_idx
= 0;
/* wrap around */
129
lp->
sk_count
++;
/* adjust counter */
130
dev->
trans_start
=
jiffies
;
131
132
/* If we just used up the very last entry in the
133
* TX ring on this device, tell the queueing
134
* layer to send no more.
135
*/
136
if
(lp->
sk_count
>=
MAX_SKB_BUFFERS
)
137
netif_stop_queue(dev);
138
139
/* When the TX completion hw interrupt arrives, this
140
* is when the transmit statistics are updated.
141
*/
142
143
spin_unlock_irq(&lp->
lock
);
144
145
if
(lp->
sk_count
<= 3) {
146
schedule_work
(&((
hysdn_card
*) dev->
ml_priv
)->irq_queue);
147
}
148
return
NETDEV_TX_OK
;
/* success */
149
}
/* net_send_packet */
150
151
152
153
/***********************************************************************/
154
/* acknowlegde a packet send. The network layer will be informed about */
155
/* completion */
156
/***********************************************************************/
157
void
158
hysdn_tx_netack
(
hysdn_card
*card)
159
{
160
struct
net_local
*lp = card->
netif
;
161
162
if
(!lp)
163
return
;
/* non existing device */
164
165
166
if
(!lp->
sk_count
)
167
return
;
/* error condition */
168
169
lp->
dev
->stats.tx_packets++;
170
lp->
dev
->stats.tx_bytes += lp->
skbs
[lp->
out_idx
]->len;
171
172
dev_kfree_skb(lp->
skbs
[lp->
out_idx
++]);
/* free skb */
173
if
(lp->
out_idx
>=
MAX_SKB_BUFFERS
)
174
lp->
out_idx
= 0;
/* wrap around */
175
176
if
(lp->
sk_count
-- ==
MAX_SKB_BUFFERS
)
/* dec usage count */
177
netif_start_queue((
struct
net_device
*) lp);
178
}
/* hysdn_tx_netack */
179
180
/*****************************************************/
181
/* we got a packet from the network, go and queue it */
182
/*****************************************************/
183
void
184
hysdn_rx_netpkt
(
hysdn_card
*card,
unsigned
char
*
buf
,
unsigned
short
len)
185
{
186
struct
net_local
*lp = card->
netif
;
187
struct
net_device
*
dev
;
188
struct
sk_buff
*
skb
;
189
190
if
(!lp)
191
return
;
/* non existing device */
192
193
dev = lp->
dev
;
194
dev->
stats
.rx_bytes +=
len
;
195
196
skb = dev_alloc_skb(len);
197
if
(skb ==
NULL
) {
198
printk
(
KERN_NOTICE
"%s: Memory squeeze, dropping packet.\n"
,
199
dev->
name
);
200
dev->
stats
.rx_dropped++;
201
return
;
202
}
203
/* copy the data */
204
memcpy
(
skb_put
(skb, len), buf, len);
205
206
/* determine the used protocol */
207
skb->
protocol
=
eth_type_trans
(skb, dev);
208
209
dev->
stats
.rx_packets++;
/* adjust packet count */
210
211
netif_rx
(skb);
212
}
/* hysdn_rx_netpkt */
213
214
/*****************************************************/
215
/* return the pointer to a network packet to be send */
216
/*****************************************************/
217
struct
sk_buff
*
218
hysdn_tx_netget
(
hysdn_card
*card)
219
{
220
struct
net_local
*lp = card->
netif
;
221
222
if
(!lp)
223
return
(
NULL
);
/* non existing device */
224
225
if
(!lp->
sk_count
)
226
return
(
NULL
);
/* nothing available */
227
228
return
(lp->
skbs
[lp->
out_idx
]);
/* next packet to send */
229
}
/* hysdn_tx_netget */
230
231
static
const
struct
net_device_ops
hysdn_netdev_ops = {
232
.ndo_open = net_open,
233
.ndo_stop = net_close,
234
.ndo_start_xmit = net_send_packet,
235
.ndo_change_mtu =
eth_change_mtu
,
236
.ndo_set_mac_address =
eth_mac_addr
,
237
.ndo_validate_addr =
eth_validate_addr
,
238
};
239
240
241
/*****************************************************************************/
242
/* hysdn_net_create creates a new net device for the given card. If a device */
243
/* already exists, it will be deleted and created a new one. The return value */
244
/* 0 announces success, else a negative error code will be returned. */
245
/*****************************************************************************/
246
int
247
hysdn_net_create
(
hysdn_card
*card)
248
{
249
struct
net_device
*
dev
;
250
int
i
;
251
struct
net_local
*lp;
252
253
if
(!card) {
254
printk
(
KERN_WARNING
"No card-pt in hysdn_net_create!\n"
);
255
return
(-
ENOMEM
);
256
}
257
hysdn_net_release
(card);
/* release an existing net device */
258
259
dev = alloc_etherdev(
sizeof
(
struct
net_local
));
260
if
(!dev) {
261
printk
(
KERN_WARNING
"HYSDN: unable to allocate mem\n"
);
262
return
(-
ENOMEM
);
263
}
264
265
lp = netdev_priv(dev);
266
lp->
dev
=
dev
;
267
268
dev->
netdev_ops
= &hysdn_netdev_ops;
269
spin_lock_init
(&((
struct
net_local
*) dev)->
lock
);
270
271
/* initialise necessary or informing fields */
272
dev->
base_addr
= card->
iobase
;
/* IO address */
273
dev->
irq
= card->
irq
;
/* irq */
274
275
dev->
netdev_ops
= &hysdn_netdev_ops;
276
if
((i =
register_netdev
(dev))) {
277
printk
(
KERN_WARNING
"HYSDN: unable to create network device\n"
);
278
free_netdev
(dev);
279
return
(i);
280
}
281
dev->
ml_priv
=
card
;
/* remember pointer to own data structure */
282
card->
netif
=
dev
;
/* setup the local pointer */
283
284
if
(card->
debug_flags
&
LOG_NET_INIT
)
285
hysdn_addlog
(card,
"network device created"
);
286
return
(0);
/* and return success */
287
}
/* hysdn_net_create */
288
289
/***************************************************************************/
290
/* hysdn_net_release deletes the net device for the given card. The return */
291
/* value 0 announces success, else a negative error code will be returned. */
292
/***************************************************************************/
293
int
294
hysdn_net_release
(
hysdn_card
*card)
295
{
296
struct
net_device
*dev = card->
netif
;
297
298
if
(!dev)
299
return
(0);
/* non existing */
300
301
card->
netif
=
NULL
;
/* clear out pointer */
302
net_close(dev);
303
304
flush_tx_buffers((
struct
net_local
*) dev);
/* empty buffers */
305
306
unregister_netdev
(dev);
/* release the device */
307
free_netdev
(dev);
/* release the memory allocated */
308
if
(card->
debug_flags
&
LOG_NET_INIT
)
309
hysdn_addlog
(card,
"network device deleted"
);
310
311
return
(0);
/* always successful */
312
}
/* hysdn_net_release */
313
314
/*****************************************************************************/
315
/* hysdn_net_getname returns a pointer to the name of the network interface. */
316
/* if the interface is not existing, a "-" is returned. */
317
/*****************************************************************************/
318
char
*
319
hysdn_net_getname
(
hysdn_card
*card)
320
{
321
struct
net_device
*dev = card->
netif
;
322
323
if
(!dev)
324
return
(
"-"
);
/* non existing */
325
326
return
(dev->
name
);
327
}
/* hysdn_net_getname */
Generated on Thu Jan 10 2013 13:42:17 for Linux Kernel by
1.8.2