]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/s390/net/qeth_l2_main.c
qeth: unregister MAC addresses during recovery.
[mirror_ubuntu-bionic-kernel.git] / drivers / s390 / net / qeth_l2_main.c
CommitLineData
4a71df50
FB
1/*
2 * drivers/s390/net/qeth_l2_main.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>,
8 * Frank Blaschka <frank.blaschka@de.ibm.com>
9 */
10
74eacdb9
FB
11#define KMSG_COMPONENT "qeth"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
4a71df50
FB
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/string.h>
17#include <linux/errno.h>
18#include <linux/kernel.h>
19#include <linux/etherdevice.h>
20#include <linux/mii.h>
21#include <linux/ip.h>
22
4a71df50 23#include "qeth_core.h"
4a71df50 24
4a71df50
FB
25static int qeth_l2_set_offline(struct ccwgroup_device *);
26static int qeth_l2_stop(struct net_device *);
27static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
28static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
29 enum qeth_ipa_cmds,
30 int (*reply_cb) (struct qeth_card *,
31 struct qeth_reply*,
32 unsigned long));
33static void qeth_l2_set_multicast_list(struct net_device *);
34static int qeth_l2_recover(void *);
35
36static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
37{
509e2562 38 struct qeth_card *card = dev->ml_priv;
4a71df50
FB
39 struct mii_ioctl_data *mii_data;
40 int rc = 0;
41
42 if (!card)
43 return -ENODEV;
44
45 if ((card->state != CARD_STATE_UP) &&
46 (card->state != CARD_STATE_SOFTSETUP))
47 return -ENODEV;
48
49 if (card->info.type == QETH_CARD_TYPE_OSN)
50 return -EPERM;
51
52 switch (cmd) {
53 case SIOC_QETH_ADP_SET_SNMP_CONTROL:
54 rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
55 break;
56 case SIOC_QETH_GET_CARD_TYPE:
57 if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
58 !card->info.guestlan)
59 return 1;
60 return 0;
61 break;
62 case SIOCGMIIPHY:
63 mii_data = if_mii(rq);
64 mii_data->phy_id = 0;
65 break;
66 case SIOCGMIIREG:
67 mii_data = if_mii(rq);
68 if (mii_data->phy_id != 0)
69 rc = -EINVAL;
70 else
71 mii_data->val_out = qeth_mdio_read(dev,
72 mii_data->phy_id, mii_data->reg_num);
73 break;
74 default:
75 rc = -EOPNOTSUPP;
76 }
77 if (rc)
d11ba0c4 78 QETH_DBF_TEXT_(TRACE, 2, "ioce%d", rc);
4a71df50
FB
79 return rc;
80}
81
82static int qeth_l2_verify_dev(struct net_device *dev)
83{
84 struct qeth_card *card;
85 unsigned long flags;
86 int rc = 0;
87
88 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
89 list_for_each_entry(card, &qeth_core_card_list.list, list) {
90 if (card->dev == dev) {
91 rc = QETH_REAL_CARD;
92 break;
93 }
94 }
95 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
96
97 return rc;
98}
99
100static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no)
101{
102 struct qeth_card *card;
103 struct net_device *ndev;
f06f6f32 104 __u16 temp_dev_no;
4a71df50 105 unsigned long flags;
f06f6f32 106 struct ccw_dev_id read_devid;
4a71df50
FB
107
108 ndev = NULL;
109 memcpy(&temp_dev_no, read_dev_no, 2);
110 read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
111 list_for_each_entry(card, &qeth_core_card_list.list, list) {
f06f6f32
CH
112 ccw_device_get_id(CARD_RDEV(card), &read_devid);
113 if (read_devid.devno == temp_dev_no) {
4a71df50
FB
114 ndev = card->dev;
115 break;
116 }
117 }
118 read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
119 return ndev;
120}
121
122static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card,
123 struct qeth_reply *reply,
124 unsigned long data)
125{
126 struct qeth_ipa_cmd *cmd;
127 __u8 *mac;
128
d11ba0c4 129 QETH_DBF_TEXT(TRACE, 2, "L2Sgmacb");
4a71df50
FB
130 cmd = (struct qeth_ipa_cmd *) data;
131 mac = &cmd->data.setdelmac.mac[0];
132 /* MAC already registered, needed in couple/uncouple case */
133 if (cmd->hdr.return_code == 0x2005) {
7c510e4b
JB
134 QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n",
135 mac, QETH_CARD_IFNAME(card));
4a71df50
FB
136 cmd->hdr.return_code = 0;
137 }
138 if (cmd->hdr.return_code)
7c510e4b
JB
139 QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n",
140 mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code);
4a71df50
FB
141 return 0;
142}
143
144static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
145{
d11ba0c4 146 QETH_DBF_TEXT(TRACE, 2, "L2Sgmac");
4a71df50
FB
147 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
148 qeth_l2_send_setgroupmac_cb);
149}
150
151static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card,
152 struct qeth_reply *reply,
153 unsigned long data)
154{
155 struct qeth_ipa_cmd *cmd;
156 __u8 *mac;
157
d11ba0c4 158 QETH_DBF_TEXT(TRACE, 2, "L2Dgmacb");
4a71df50
FB
159 cmd = (struct qeth_ipa_cmd *) data;
160 mac = &cmd->data.setdelmac.mac[0];
161 if (cmd->hdr.return_code)
7c510e4b
JB
162 QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n",
163 mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code);
4a71df50
FB
164 return 0;
165}
166
167static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
168{
d11ba0c4 169 QETH_DBF_TEXT(TRACE, 2, "L2Dgmac");
4a71df50
FB
170 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC,
171 qeth_l2_send_delgroupmac_cb);
172}
173
7db2266a 174static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
4a71df50
FB
175{
176 struct qeth_mc_mac *mc;
7db2266a 177 int rc;
4a71df50
FB
178
179 mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC);
180
14cc21b6 181 if (!mc)
4a71df50 182 return;
4a71df50
FB
183
184 memcpy(mc->mc_addr, mac, OSA_ADDR_LEN);
185 mc->mc_addrlen = OSA_ADDR_LEN;
7db2266a
FB
186 mc->is_vmac = vmac;
187
188 if (vmac) {
189 rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
190 NULL);
191 } else {
192 rc = qeth_l2_send_setgroupmac(card, mac);
193 }
4a71df50 194
7db2266a 195 if (!rc)
4a71df50
FB
196 list_add_tail(&mc->list, &card->mc_list);
197 else
198 kfree(mc);
199}
200
201static void qeth_l2_del_all_mc(struct qeth_card *card)
202{
203 struct qeth_mc_mac *mc, *tmp;
204
205 spin_lock_bh(&card->mclock);
206 list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
7db2266a
FB
207 if (mc->is_vmac)
208 qeth_l2_send_setdelmac(card, mc->mc_addr,
209 IPA_CMD_DELVMAC, NULL);
210 else
211 qeth_l2_send_delgroupmac(card, mc->mc_addr);
4a71df50
FB
212 list_del(&mc->list);
213 kfree(mc);
214 }
215 spin_unlock_bh(&card->mclock);
216}
217
218static void qeth_l2_get_packet_type(struct qeth_card *card,
219 struct qeth_hdr *hdr, struct sk_buff *skb)
220{
221 __u16 hdr_mac;
222
223 if (!memcmp(skb->data + QETH_HEADER_SIZE,
224 skb->dev->broadcast, 6)) {
225 /* broadcast? */
226 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
227 return;
228 }
229 hdr_mac = *((__u16 *)skb->data);
230 /* tr multicast? */
231 switch (card->info.link_type) {
232 case QETH_LINK_TYPE_HSTR:
233 case QETH_LINK_TYPE_LANE_TR:
234 if ((hdr_mac == QETH_TR_MAC_NC) ||
235 (hdr_mac == QETH_TR_MAC_C))
236 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
237 else
238 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
239 break;
240 /* eth or so multicast? */
241 default:
242 if ((hdr_mac == QETH_ETH_MAC_V4) ||
243 (hdr_mac == QETH_ETH_MAC_V6))
244 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
245 else
246 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
247 }
248}
249
250static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
251 struct sk_buff *skb, int ipv, int cast_type)
252{
683d718a 253 struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb);
4a71df50
FB
254
255 memset(hdr, 0, sizeof(struct qeth_hdr));
256 hdr->hdr.l2.id = QETH_HEADER_TYPE_LAYER2;
257
258 /* set byte byte 3 to casting flags */
259 if (cast_type == RTN_MULTICAST)
260 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
261 else if (cast_type == RTN_BROADCAST)
262 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
263 else
264 qeth_l2_get_packet_type(card, hdr, skb);
265
266 hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE;
267 /* VSWITCH relies on the VLAN
268 * information to be present in
269 * the QDIO header */
270 if (veth->h_vlan_proto == __constant_htons(ETH_P_8021Q)) {
271 hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_VLAN;
272 hdr->hdr.l2.vlan_id = ntohs(veth->h_vlan_TCI);
273 }
274}
275
276static int qeth_l2_send_setdelvlan_cb(struct qeth_card *card,
277 struct qeth_reply *reply, unsigned long data)
278{
279 struct qeth_ipa_cmd *cmd;
280
d11ba0c4 281 QETH_DBF_TEXT(TRACE, 2, "L2sdvcb");
4a71df50
FB
282 cmd = (struct qeth_ipa_cmd *) data;
283 if (cmd->hdr.return_code) {
14cc21b6 284 QETH_DBF_MESSAGE(2, "Error in processing VLAN %i on %s: 0x%x. "
4a71df50
FB
285 "Continuing\n", cmd->data.setdelvlan.vlan_id,
286 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
d11ba0c4
PT
287 QETH_DBF_TEXT_(TRACE, 2, "L2VL%4x", cmd->hdr.command);
288 QETH_DBF_TEXT_(TRACE, 2, "L2%s", CARD_BUS_ID(card));
289 QETH_DBF_TEXT_(TRACE, 2, "err%d", cmd->hdr.return_code);
4a71df50
FB
290 }
291 return 0;
292}
293
294static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
295 enum qeth_ipa_cmds ipacmd)
296{
297 struct qeth_ipa_cmd *cmd;
298 struct qeth_cmd_buffer *iob;
299
d11ba0c4 300 QETH_DBF_TEXT_(TRACE, 4, "L2sdv%x", ipacmd);
4a71df50
FB
301 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
302 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
303 cmd->data.setdelvlan.vlan_id = i;
304 return qeth_send_ipa_cmd(card, iob,
305 qeth_l2_send_setdelvlan_cb, NULL);
306}
307
308static void qeth_l2_process_vlans(struct qeth_card *card, int clear)
309{
310 struct qeth_vlan_vid *id;
d11ba0c4 311 QETH_DBF_TEXT(TRACE, 3, "L2prcvln");
4a71df50
FB
312 spin_lock_bh(&card->vlanlock);
313 list_for_each_entry(id, &card->vid_list, list) {
314 if (clear)
315 qeth_l2_send_setdelvlan(card, id->vid,
316 IPA_CMD_DELVLAN);
317 else
318 qeth_l2_send_setdelvlan(card, id->vid,
319 IPA_CMD_SETVLAN);
320 }
321 spin_unlock_bh(&card->vlanlock);
322}
323
324static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
325{
509e2562 326 struct qeth_card *card = dev->ml_priv;
4a71df50
FB
327 struct qeth_vlan_vid *id;
328
d11ba0c4 329 QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid);
4a71df50
FB
330 id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC);
331 if (id) {
332 id->vid = vid;
333 qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
334 spin_lock_bh(&card->vlanlock);
335 list_add_tail(&id->list, &card->vid_list);
336 spin_unlock_bh(&card->vlanlock);
4a71df50
FB
337 }
338}
339
340static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
341{
342 struct qeth_vlan_vid *id, *tmpid = NULL;
509e2562 343 struct qeth_card *card = dev->ml_priv;
4a71df50 344
d11ba0c4 345 QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid);
4a71df50
FB
346 spin_lock_bh(&card->vlanlock);
347 list_for_each_entry(id, &card->vid_list, list) {
348 if (id->vid == vid) {
349 list_del(&id->list);
350 tmpid = id;
351 break;
352 }
353 }
354 spin_unlock_bh(&card->vlanlock);
355 if (tmpid) {
356 qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
357 kfree(tmpid);
358 }
359 qeth_l2_set_multicast_list(card->dev);
360}
361
362static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
363{
364 int rc = 0;
365
d11ba0c4
PT
366 QETH_DBF_TEXT(SETUP , 2, "stopcard");
367 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
4a71df50
FB
368
369 qeth_set_allowed_threads(card, 0, 1);
4a71df50
FB
370 if (card->read.state == CH_STATE_UP &&
371 card->write.state == CH_STATE_UP &&
372 (card->state == CARD_STATE_UP)) {
373 if (recovery_mode &&
374 card->info.type != QETH_CARD_TYPE_OSN) {
375 qeth_l2_stop(card->dev);
376 } else {
377 rtnl_lock();
378 dev_close(card->dev);
379 rtnl_unlock();
380 }
932e1583
KDW
381 if (!card->use_hard_stop ||
382 recovery_mode) {
4a71df50
FB
383 __u8 *mac = &card->dev->dev_addr[0];
384 rc = qeth_l2_send_delmac(card, mac);
d11ba0c4 385 QETH_DBF_TEXT_(SETUP, 2, "Lerr%d", rc);
4a71df50
FB
386 }
387 card->state = CARD_STATE_SOFTSETUP;
388 }
389 if (card->state == CARD_STATE_SOFTSETUP) {
390 qeth_l2_process_vlans(card, 1);
932e1583
KDW
391 if (!card->use_hard_stop ||
392 recovery_mode)
28a7e4c9 393 qeth_l2_del_all_mc(card);
4a71df50
FB
394 qeth_clear_ipacmd_list(card);
395 card->state = CARD_STATE_HARDSETUP;
396 }
397 if (card->state == CARD_STATE_HARDSETUP) {
398 qeth_qdio_clear_card(card, 0);
399 qeth_clear_qdio_buffers(card);
400 qeth_clear_working_pool_list(card);
401 card->state = CARD_STATE_DOWN;
402 }
403 if (card->state == CARD_STATE_DOWN) {
404 qeth_clear_cmd_buffers(&card->read);
405 qeth_clear_cmd_buffers(&card->write);
406 }
407 card->use_hard_stop = 0;
408 return rc;
409}
410
411static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
412 struct qeth_qdio_buffer *buf, int index)
413{
414 struct qdio_buffer_element *element;
415 struct sk_buff *skb;
416 struct qeth_hdr *hdr;
417 int offset;
418 unsigned int len;
419
420 /* get first element of current buffer */
421 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
422 offset = 0;
423 if (card->options.performance_stats)
424 card->perf_stats.bufs_rec++;
425 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
426 &offset, &hdr))) {
427 skb->dev = card->dev;
428 /* is device UP ? */
429 if (!(card->dev->flags & IFF_UP)) {
430 dev_kfree_skb_any(skb);
431 continue;
432 }
433
434 switch (hdr->hdr.l2.id) {
435 case QETH_HEADER_TYPE_LAYER2:
436 skb->pkt_type = PACKET_HOST;
437 skb->protocol = eth_type_trans(skb, skb->dev);
438 if (card->options.checksum_type == NO_CHECKSUMMING)
439 skb->ip_summed = CHECKSUM_UNNECESSARY;
440 else
441 skb->ip_summed = CHECKSUM_NONE;
12883725
UB
442 if (skb->protocol == htons(ETH_P_802_2))
443 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
4a71df50
FB
444 len = skb->len;
445 netif_rx(skb);
446 break;
447 case QETH_HEADER_TYPE_OSN:
2d488c2f
UB
448 if (card->info.type == QETH_CARD_TYPE_OSN) {
449 skb_push(skb, sizeof(struct qeth_hdr));
450 skb_copy_to_linear_data(skb, hdr,
4a71df50 451 sizeof(struct qeth_hdr));
2d488c2f
UB
452 len = skb->len;
453 card->osn_info.data_cb(skb);
454 break;
455 }
456 /* else unknown */
4a71df50
FB
457 default:
458 dev_kfree_skb_any(skb);
d11ba0c4
PT
459 QETH_DBF_TEXT(TRACE, 3, "inbunkno");
460 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
4a71df50
FB
461 continue;
462 }
463 card->dev->last_rx = jiffies;
464 card->stats.rx_packets++;
465 card->stats.rx_bytes += len;
466 }
467}
468
469static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
470 enum qeth_ipa_cmds ipacmd,
471 int (*reply_cb) (struct qeth_card *,
472 struct qeth_reply*,
473 unsigned long))
474{
475 struct qeth_ipa_cmd *cmd;
476 struct qeth_cmd_buffer *iob;
477
d11ba0c4 478 QETH_DBF_TEXT(TRACE, 2, "L2sdmac");
4a71df50
FB
479 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
480 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
481 cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
482 memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
483 return qeth_send_ipa_cmd(card, iob, reply_cb, NULL);
484}
485
486static int qeth_l2_send_setmac_cb(struct qeth_card *card,
487 struct qeth_reply *reply,
488 unsigned long data)
489{
490 struct qeth_ipa_cmd *cmd;
491
d11ba0c4 492 QETH_DBF_TEXT(TRACE, 2, "L2Smaccb");
4a71df50
FB
493 cmd = (struct qeth_ipa_cmd *) data;
494 if (cmd->hdr.return_code) {
d11ba0c4 495 QETH_DBF_TEXT_(TRACE, 2, "L2er%x", cmd->hdr.return_code);
4a71df50
FB
496 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
497 cmd->hdr.return_code = -EIO;
498 } else {
499 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
500 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
501 OSA_ADDR_LEN);
74eacdb9
FB
502 dev_info(&card->gdev->dev,
503 "MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
504 "successfully registered on device %s\n",
505 card->dev->dev_addr[0], card->dev->dev_addr[1],
506 card->dev->dev_addr[2], card->dev->dev_addr[3],
507 card->dev->dev_addr[4], card->dev->dev_addr[5],
508 card->dev->name);
4a71df50
FB
509 }
510 return 0;
511}
512
513static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
514{
d11ba0c4 515 QETH_DBF_TEXT(TRACE, 2, "L2Setmac");
4a71df50
FB
516 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
517 qeth_l2_send_setmac_cb);
518}
519
520static int qeth_l2_send_delmac_cb(struct qeth_card *card,
521 struct qeth_reply *reply,
522 unsigned long data)
523{
524 struct qeth_ipa_cmd *cmd;
525
d11ba0c4 526 QETH_DBF_TEXT(TRACE, 2, "L2Dmaccb");
4a71df50
FB
527 cmd = (struct qeth_ipa_cmd *) data;
528 if (cmd->hdr.return_code) {
d11ba0c4 529 QETH_DBF_TEXT_(TRACE, 2, "err%d", cmd->hdr.return_code);
4a71df50
FB
530 cmd->hdr.return_code = -EIO;
531 return 0;
532 }
533 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
534
535 return 0;
536}
537
538static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
539{
d11ba0c4 540 QETH_DBF_TEXT(TRACE, 2, "L2Delmac");
4a71df50
FB
541 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
542 return 0;
543 return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
544 qeth_l2_send_delmac_cb);
545}
546
547static int qeth_l2_request_initial_mac(struct qeth_card *card)
548{
549 int rc = 0;
550 char vendor_pre[] = {0x02, 0x00, 0x00};
551
d11ba0c4
PT
552 QETH_DBF_TEXT(SETUP, 2, "doL2init");
553 QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card));
4a71df50
FB
554
555 rc = qeth_query_setadapterparms(card);
556 if (rc) {
14cc21b6
FB
557 QETH_DBF_MESSAGE(2, "could not query adapter parameters on "
558 "device %s: x%x\n", CARD_BUS_ID(card), rc);
4a71df50
FB
559 }
560
f1d58672
UB
561 if ((card->info.type == QETH_CARD_TYPE_IQD) ||
562 (card->info.guestlan)) {
4a71df50
FB
563 rc = qeth_setadpparms_change_macaddr(card);
564 if (rc) {
14cc21b6
FB
565 QETH_DBF_MESSAGE(2, "couldn't get MAC address on "
566 "device %s: x%x\n", CARD_BUS_ID(card), rc);
d11ba0c4 567 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50
FB
568 return rc;
569 }
d11ba0c4 570 QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN);
4a71df50
FB
571 } else {
572 random_ether_addr(card->dev->dev_addr);
573 memcpy(card->dev->dev_addr, vendor_pre, 3);
574 }
575 return 0;
576}
577
578static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
579{
580 struct sockaddr *addr = p;
509e2562 581 struct qeth_card *card = dev->ml_priv;
4a71df50
FB
582 int rc = 0;
583
d11ba0c4 584 QETH_DBF_TEXT(TRACE, 3, "setmac");
4a71df50
FB
585
586 if (qeth_l2_verify_dev(dev) != QETH_REAL_CARD) {
d11ba0c4 587 QETH_DBF_TEXT(TRACE, 3, "setmcINV");
4a71df50
FB
588 return -EOPNOTSUPP;
589 }
590
591 if (card->info.type == QETH_CARD_TYPE_OSN) {
d11ba0c4 592 QETH_DBF_TEXT(TRACE, 3, "setmcOSN");
4a71df50
FB
593 return -EOPNOTSUPP;
594 }
d11ba0c4
PT
595 QETH_DBF_TEXT_(TRACE, 3, "%s", CARD_BUS_ID(card));
596 QETH_DBF_HEX(TRACE, 3, addr->sa_data, OSA_ADDR_LEN);
4a71df50
FB
597 rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
598 if (!rc)
599 rc = qeth_l2_send_setmac(card, addr->sa_data);
600 return rc;
601}
602
603static void qeth_l2_set_multicast_list(struct net_device *dev)
604{
509e2562 605 struct qeth_card *card = dev->ml_priv;
7db2266a 606 struct dev_addr_list *dm;
4a71df50
FB
607
608 if (card->info.type == QETH_CARD_TYPE_OSN)
609 return ;
610
d11ba0c4 611 QETH_DBF_TEXT(TRACE, 3, "setmulti");
4a71df50
FB
612 qeth_l2_del_all_mc(card);
613 spin_lock_bh(&card->mclock);
614 for (dm = dev->mc_list; dm; dm = dm->next)
7db2266a
FB
615 qeth_l2_add_mc(card, dm->da_addr, 0);
616
617 for (dm = dev->uc_list; dm; dm = dm->next)
618 qeth_l2_add_mc(card, dm->da_addr, 1);
619
4a71df50
FB
620 spin_unlock_bh(&card->mclock);
621 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
622 return;
623 qeth_setadp_promisc_mode(card);
624}
625
626static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
627{
628 int rc;
629 struct qeth_hdr *hdr = NULL;
630 int elements = 0;
509e2562 631 struct qeth_card *card = dev->ml_priv;
4a71df50
FB
632 struct sk_buff *new_skb = skb;
633 int ipv = qeth_get_ip_version(skb);
634 int cast_type = qeth_get_cast_type(card, skb);
635 struct qeth_qdio_out_q *queue = card->qdio.out_qs
636 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
637 int tx_bytes = skb->len;
683d718a
FB
638 int data_offset = -1;
639 int elements_needed = 0;
640 int hd_len = 0;
4a71df50 641
4a71df50
FB
642 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
643 card->stats.tx_carrier_errors++;
644 goto tx_drop;
645 }
646
647 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
648 (skb->protocol == htons(ETH_P_IPV6)))
649 goto tx_drop;
650
651 if (card->options.performance_stats) {
652 card->perf_stats.outbound_cnt++;
653 card->perf_stats.outbound_start_time = qeth_get_micros();
654 }
655 netif_stop_queue(dev);
656
4a71df50
FB
657 if (card->info.type == QETH_CARD_TYPE_OSN)
658 hdr = (struct qeth_hdr *)skb->data;
659 else {
64ef8957 660 if (card->info.type == QETH_CARD_TYPE_IQD) {
683d718a
FB
661 new_skb = skb;
662 data_offset = ETH_HLEN;
663 hd_len = ETH_HLEN;
664 hdr = kmem_cache_alloc(qeth_core_header_cache,
665 GFP_ATOMIC);
666 if (!hdr)
667 goto tx_drop;
668 elements_needed++;
669 skb_reset_mac_header(new_skb);
670 qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type);
671 hdr->hdr.l2.pkt_length = new_skb->len;
672 memcpy(((char *)hdr) + sizeof(struct qeth_hdr),
673 skb_mac_header(new_skb), ETH_HLEN);
674 } else {
675 /* create a clone with writeable headroom */
676 new_skb = skb_realloc_headroom(skb,
677 sizeof(struct qeth_hdr));
678 if (!new_skb)
679 goto tx_drop;
680 hdr = (struct qeth_hdr *)skb_push(new_skb,
f90b744e 681 sizeof(struct qeth_hdr));
683d718a
FB
682 skb_set_mac_header(new_skb, sizeof(struct qeth_hdr));
683 qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type);
684 }
4a71df50
FB
685 }
686
64ef8957 687 elements = qeth_get_elements_no(card, (void *)hdr, new_skb,
683d718a 688 elements_needed);
64ef8957
FB
689 if (!elements) {
690 if (data_offset >= 0)
691 kmem_cache_free(qeth_core_header_cache, hdr);
692 goto tx_drop;
f61a0d05 693 }
4a71df50
FB
694
695 if (card->info.type != QETH_CARD_TYPE_IQD)
696 rc = qeth_do_send_packet(card, queue, new_skb, hdr,
64ef8957 697 elements);
4a71df50
FB
698 else
699 rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
64ef8957 700 elements, data_offset, hd_len);
4a71df50
FB
701 if (!rc) {
702 card->stats.tx_packets++;
703 card->stats.tx_bytes += tx_bytes;
704 if (new_skb != skb)
705 dev_kfree_skb_any(skb);
4a71df50 706 } else {
683d718a
FB
707 if (data_offset >= 0)
708 kmem_cache_free(qeth_core_header_cache, hdr);
709
4a71df50
FB
710 if (rc == -EBUSY) {
711 if (new_skb != skb)
712 dev_kfree_skb_any(new_skb);
713 return NETDEV_TX_BUSY;
714 } else
715 goto tx_drop;
716 }
717
718 netif_wake_queue(dev);
719 if (card->options.performance_stats)
720 card->perf_stats.outbound_time += qeth_get_micros() -
721 card->perf_stats.outbound_start_time;
722 return rc;
723
724tx_drop:
725 card->stats.tx_dropped++;
726 card->stats.tx_errors++;
727 if ((new_skb != skb) && new_skb)
728 dev_kfree_skb_any(new_skb);
729 dev_kfree_skb_any(skb);
d0ec0f54 730 netif_wake_queue(dev);
4a71df50
FB
731 return NETDEV_TX_OK;
732}
733
734static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
779e6e1c 735 unsigned int qdio_err, unsigned int queue,
4a71df50
FB
736 int first_element, int count, unsigned long card_ptr)
737{
738 struct net_device *net_dev;
739 struct qeth_card *card;
740 struct qeth_qdio_buffer *buffer;
741 int index;
742 int i;
743
4a71df50
FB
744 card = (struct qeth_card *) card_ptr;
745 net_dev = card->dev;
746 if (card->options.performance_stats) {
747 card->perf_stats.inbound_cnt++;
748 card->perf_stats.inbound_start_time = qeth_get_micros();
749 }
779e6e1c
JG
750 if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
751 QETH_DBF_TEXT(TRACE, 1, "qdinchk");
752 QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
753 QETH_DBF_TEXT_(TRACE, 1, "%04X%04X", first_element,
754 count);
755 QETH_DBF_TEXT_(TRACE, 1, "%04X", queue);
756 qeth_schedule_recovery(card);
757 return;
4a71df50
FB
758 }
759 for (i = first_element; i < (first_element + count); ++i) {
760 index = i % QDIO_MAX_BUFFERS_PER_Q;
761 buffer = &card->qdio.in_q->bufs[index];
779e6e1c
JG
762 if (!(qdio_err &&
763 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr")))
4a71df50
FB
764 qeth_l2_process_inbound_buffer(card, buffer, index);
765 /* clear buffer and give back to hardware */
766 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
767 qeth_queue_input_buffer(card, index);
768 }
769 if (card->options.performance_stats)
770 card->perf_stats.inbound_time += qeth_get_micros() -
771 card->perf_stats.inbound_start_time;
772}
773
774static int qeth_l2_open(struct net_device *dev)
775{
509e2562 776 struct qeth_card *card = dev->ml_priv;
4a71df50 777
d11ba0c4 778 QETH_DBF_TEXT(TRACE, 4, "qethopen");
4a71df50
FB
779 if (card->state != CARD_STATE_SOFTSETUP)
780 return -ENODEV;
781
782 if ((card->info.type != QETH_CARD_TYPE_OSN) &&
783 (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
d11ba0c4 784 QETH_DBF_TEXT(TRACE, 4, "nomacadr");
4a71df50
FB
785 return -EPERM;
786 }
787 card->data.state = CH_STATE_UP;
788 card->state = CARD_STATE_UP;
4a71df50
FB
789 netif_start_queue(dev);
790
791 if (!card->lan_online && netif_carrier_ok(dev))
792 netif_carrier_off(dev);
793 return 0;
794}
795
796
797static int qeth_l2_stop(struct net_device *dev)
798{
509e2562 799 struct qeth_card *card = dev->ml_priv;
4a71df50 800
d11ba0c4 801 QETH_DBF_TEXT(TRACE, 4, "qethstop");
4a71df50 802 netif_tx_disable(dev);
4a71df50
FB
803 if (card->state == CARD_STATE_UP)
804 card->state = CARD_STATE_SOFTSETUP;
805 return 0;
806}
807
808static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
809{
810 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
811
812 INIT_LIST_HEAD(&card->vid_list);
813 INIT_LIST_HEAD(&card->mc_list);
814 card->options.layer2 = 1;
815 card->discipline.input_handler = (qdio_handler_t *)
816 qeth_l2_qdio_input_handler;
817 card->discipline.output_handler = (qdio_handler_t *)
818 qeth_qdio_output_handler;
819 card->discipline.recover = qeth_l2_recover;
820 return 0;
821}
822
823static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
824{
825 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
826
827 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
828
829 if (cgdev->state == CCWGROUP_ONLINE) {
830 card->use_hard_stop = 1;
831 qeth_l2_set_offline(cgdev);
832 }
833
834 if (card->dev) {
835 unregister_netdev(card->dev);
836 card->dev = NULL;
837 }
838
839 qeth_l2_del_all_mc(card);
840 return;
841}
842
843static struct ethtool_ops qeth_l2_ethtool_ops = {
844 .get_link = ethtool_op_get_link,
4a71df50
FB
845 .get_strings = qeth_core_get_strings,
846 .get_ethtool_stats = qeth_core_get_ethtool_stats,
847 .get_stats_count = qeth_core_get_stats_count,
848 .get_drvinfo = qeth_core_get_drvinfo,
3f9975aa 849 .get_settings = qeth_core_ethtool_get_settings,
4a71df50
FB
850};
851
852static struct ethtool_ops qeth_l2_osn_ops = {
853 .get_strings = qeth_core_get_strings,
854 .get_ethtool_stats = qeth_core_get_ethtool_stats,
855 .get_stats_count = qeth_core_get_stats_count,
856 .get_drvinfo = qeth_core_get_drvinfo,
857};
858
3d58cefd 859static const struct net_device_ops qeth_l2_netdev_ops = {
8403b13c
FB
860 .ndo_open = qeth_l2_open,
861 .ndo_stop = qeth_l2_stop,
862 .ndo_get_stats = qeth_get_stats,
863 .ndo_start_xmit = qeth_l2_hard_start_xmit,
864 .ndo_validate_addr = eth_validate_addr,
865 .ndo_set_multicast_list = qeth_l2_set_multicast_list,
866 .ndo_do_ioctl = qeth_l2_do_ioctl,
867 .ndo_set_mac_address = qeth_l2_set_mac_address,
868 .ndo_change_mtu = qeth_change_mtu,
869 .ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid,
870 .ndo_vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid,
871 .ndo_tx_timeout = qeth_tx_timeout,
872};
873
4a71df50
FB
874static int qeth_l2_setup_netdev(struct qeth_card *card)
875{
876 switch (card->info.type) {
877 case QETH_CARD_TYPE_OSAE:
878 card->dev = alloc_etherdev(0);
879 break;
880 case QETH_CARD_TYPE_IQD:
881 card->dev = alloc_netdev(0, "hsi%d", ether_setup);
882 break;
883 case QETH_CARD_TYPE_OSN:
884 card->dev = alloc_netdev(0, "osn%d", ether_setup);
885 card->dev->flags |= IFF_NOARP;
886 break;
887 default:
888 card->dev = alloc_etherdev(0);
889 }
890
891 if (!card->dev)
892 return -ENODEV;
893
509e2562 894 card->dev->ml_priv = card;
4a71df50 895 card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
4a71df50 896 card->dev->mtu = card->info.initial_mtu;
8403b13c 897 card->dev->netdev_ops = &qeth_l2_netdev_ops;
4a71df50
FB
898 if (card->info.type != QETH_CARD_TYPE_OSN)
899 SET_ETHTOOL_OPS(card->dev, &qeth_l2_ethtool_ops);
900 else
901 SET_ETHTOOL_OPS(card->dev, &qeth_l2_osn_ops);
902 card->dev->features |= NETIF_F_HW_VLAN_FILTER;
903 card->info.broadcast_capable = 1;
904 qeth_l2_request_initial_mac(card);
905 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
906 return register_netdev(card->dev);
907}
908
909static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
910{
911 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
912 int rc = 0;
913 enum qeth_card_states recover_flag;
914
915 BUG_ON(!card);
d11ba0c4
PT
916 QETH_DBF_TEXT(SETUP, 2, "setonlin");
917 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
4a71df50
FB
918
919 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
4a71df50
FB
920 recover_flag = card->state;
921 rc = ccw_device_set_online(CARD_RDEV(card));
922 if (rc) {
d11ba0c4 923 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50
FB
924 return -EIO;
925 }
926 rc = ccw_device_set_online(CARD_WDEV(card));
927 if (rc) {
d11ba0c4 928 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50
FB
929 return -EIO;
930 }
931 rc = ccw_device_set_online(CARD_DDEV(card));
932 if (rc) {
d11ba0c4 933 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50
FB
934 return -EIO;
935 }
936
937 rc = qeth_core_hardsetup_card(card);
938 if (rc) {
d11ba0c4 939 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
4a71df50
FB
940 goto out_remove;
941 }
942
943 if (!card->dev && qeth_l2_setup_netdev(card))
944 goto out_remove;
945
946 if (card->info.type != QETH_CARD_TYPE_OSN)
947 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
948
949 card->state = CARD_STATE_HARDSETUP;
950 qeth_print_status_message(card);
951
952 /* softsetup */
d11ba0c4 953 QETH_DBF_TEXT(SETUP, 2, "softsetp");
4a71df50
FB
954
955 rc = qeth_send_startlan(card);
956 if (rc) {
d11ba0c4 957 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50 958 if (rc == 0xe080) {
74eacdb9
FB
959 dev_warn(&card->gdev->dev,
960 "The LAN is offline\n");
4a71df50
FB
961 card->lan_online = 0;
962 }
963 return rc;
964 } else
965 card->lan_online = 1;
966
967 if (card->info.type != QETH_CARD_TYPE_OSN) {
968 qeth_set_large_send(card, card->options.large_send);
969 qeth_l2_process_vlans(card, 0);
970 }
971
972 netif_tx_disable(card->dev);
973
974 rc = qeth_init_qdio_queues(card);
975 if (rc) {
d11ba0c4 976 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
4a71df50
FB
977 goto out_remove;
978 }
979 card->state = CARD_STATE_SOFTSETUP;
980 netif_carrier_on(card->dev);
981
982 qeth_set_allowed_threads(card, 0xffffffff, 0);
983 if (recover_flag == CARD_STATE_RECOVER) {
984 if (recovery_mode &&
985 card->info.type != QETH_CARD_TYPE_OSN) {
986 qeth_l2_open(card->dev);
987 } else {
988 rtnl_lock();
989 dev_open(card->dev);
990 rtnl_unlock();
991 }
992 /* this also sets saved unicast addresses */
993 qeth_l2_set_multicast_list(card->dev);
994 }
995 /* let user_space know that device is online */
996 kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
997 return 0;
998out_remove:
999 card->use_hard_stop = 1;
1000 qeth_l2_stop_card(card, 0);
1001 ccw_device_set_offline(CARD_DDEV(card));
1002 ccw_device_set_offline(CARD_WDEV(card));
1003 ccw_device_set_offline(CARD_RDEV(card));
1004 if (recover_flag == CARD_STATE_RECOVER)
1005 card->state = CARD_STATE_RECOVER;
1006 else
1007 card->state = CARD_STATE_DOWN;
1008 return -ENODEV;
1009}
1010
1011static int qeth_l2_set_online(struct ccwgroup_device *gdev)
1012{
1013 return __qeth_l2_set_online(gdev, 0);
1014}
1015
1016static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
1017 int recovery_mode)
1018{
1019 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
1020 int rc = 0, rc2 = 0, rc3 = 0;
1021 enum qeth_card_states recover_flag;
1022
d11ba0c4
PT
1023 QETH_DBF_TEXT(SETUP, 3, "setoffl");
1024 QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
4a71df50
FB
1025
1026 if (card->dev && netif_carrier_ok(card->dev))
1027 netif_carrier_off(card->dev);
1028 recover_flag = card->state;
0f5623c9 1029 qeth_l2_stop_card(card, recovery_mode);
4a71df50
FB
1030 rc = ccw_device_set_offline(CARD_DDEV(card));
1031 rc2 = ccw_device_set_offline(CARD_WDEV(card));
1032 rc3 = ccw_device_set_offline(CARD_RDEV(card));
1033 if (!rc)
1034 rc = (rc2) ? rc2 : rc3;
1035 if (rc)
d11ba0c4 1036 QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
4a71df50
FB
1037 if (recover_flag == CARD_STATE_UP)
1038 card->state = CARD_STATE_RECOVER;
1039 /* let user_space know that device is offline */
1040 kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
1041 return 0;
1042}
1043
1044static int qeth_l2_set_offline(struct ccwgroup_device *cgdev)
1045{
1046 return __qeth_l2_set_offline(cgdev, 0);
1047}
1048
1049static int qeth_l2_recover(void *ptr)
1050{
1051 struct qeth_card *card;
1052 int rc = 0;
1053
1054 card = (struct qeth_card *) ptr;
d11ba0c4
PT
1055 QETH_DBF_TEXT(TRACE, 2, "recover1");
1056 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
4a71df50
FB
1057 if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
1058 return 0;
d11ba0c4 1059 QETH_DBF_TEXT(TRACE, 2, "recover2");
74eacdb9
FB
1060 dev_warn(&card->gdev->dev,
1061 "A recovery process has been started for the device\n");
4a71df50
FB
1062 card->use_hard_stop = 1;
1063 __qeth_l2_set_offline(card->gdev, 1);
1064 rc = __qeth_l2_set_online(card->gdev, 1);
1065 /* don't run another scheduled recovery */
1066 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1067 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1068 if (!rc)
74eacdb9
FB
1069 dev_info(&card->gdev->dev,
1070 "Device successfully recovered!\n");
28a7e4c9 1071 else {
fc9c2460
UB
1072 if (card->dev) {
1073 rtnl_lock();
1074 dev_close(card->dev);
1075 rtnl_unlock();
1076 }
74eacdb9
FB
1077 dev_warn(&card->gdev->dev, "The qeth device driver "
1078 "failed to recover an error on the device\n");
28a7e4c9 1079 }
4a71df50
FB
1080 return 0;
1081}
1082
1083static int __init qeth_l2_init(void)
1084{
74eacdb9 1085 pr_info("register layer 2 discipline\n");
4a71df50
FB
1086 return 0;
1087}
1088
1089static void __exit qeth_l2_exit(void)
1090{
74eacdb9 1091 pr_info("unregister layer 2 discipline\n");
4a71df50
FB
1092}
1093
1094static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
1095{
1096 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1097 qeth_qdio_clear_card(card, 0);
1098 qeth_clear_qdio_buffers(card);
1099}
1100
1101struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
1102 .probe = qeth_l2_probe_device,
1103 .remove = qeth_l2_remove_device,
1104 .set_online = qeth_l2_set_online,
1105 .set_offline = qeth_l2_set_offline,
1106 .shutdown = qeth_l2_shutdown,
1107};
1108EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver);
1109
1110static int qeth_osn_send_control_data(struct qeth_card *card, int len,
1111 struct qeth_cmd_buffer *iob)
1112{
1113 unsigned long flags;
1114 int rc = 0;
1115
d11ba0c4 1116 QETH_DBF_TEXT(TRACE, 5, "osndctrd");
4a71df50
FB
1117
1118 wait_event(card->wait_q,
1119 atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
1120 qeth_prepare_control_data(card, len, iob);
d11ba0c4 1121 QETH_DBF_TEXT(TRACE, 6, "osnoirqp");
4a71df50
FB
1122 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1123 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1124 (addr_t) iob, 0, 0);
1125 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1126 if (rc) {
14cc21b6 1127 QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
4a71df50 1128 "ccw_device_start rc = %i\n", rc);
d11ba0c4 1129 QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
4a71df50
FB
1130 qeth_release_buffer(iob->channel, iob);
1131 atomic_set(&card->write.irq_pending, 0);
1132 wake_up(&card->wait_q);
1133 }
1134 return rc;
1135}
1136
1137static int qeth_osn_send_ipa_cmd(struct qeth_card *card,
1138 struct qeth_cmd_buffer *iob, int data_len)
1139{
1140 u16 s1, s2;
1141
d11ba0c4 1142 QETH_DBF_TEXT(TRACE, 4, "osndipa");
4a71df50
FB
1143
1144 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
1145 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
1146 s2 = (u16)data_len;
1147 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
1148 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
1149 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
1150 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
1151 return qeth_osn_send_control_data(card, s1, iob);
1152}
1153
1154int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
1155{
1156 struct qeth_cmd_buffer *iob;
1157 struct qeth_card *card;
1158 int rc;
1159
d11ba0c4 1160 QETH_DBF_TEXT(TRACE, 2, "osnsdmc");
4a71df50
FB
1161 if (!dev)
1162 return -ENODEV;
509e2562 1163 card = dev->ml_priv;
4a71df50
FB
1164 if (!card)
1165 return -ENODEV;
1166 if ((card->state != CARD_STATE_UP) &&
1167 (card->state != CARD_STATE_SOFTSETUP))
1168 return -ENODEV;
1169 iob = qeth_wait_for_buffer(&card->write);
1170 memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
1171 rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
1172 return rc;
1173}
1174EXPORT_SYMBOL(qeth_osn_assist);
1175
1176int qeth_osn_register(unsigned char *read_dev_no, struct net_device **dev,
1177 int (*assist_cb)(struct net_device *, void *),
1178 int (*data_cb)(struct sk_buff *))
1179{
1180 struct qeth_card *card;
1181
d11ba0c4 1182 QETH_DBF_TEXT(TRACE, 2, "osnreg");
4a71df50
FB
1183 *dev = qeth_l2_netdev_by_devno(read_dev_no);
1184 if (*dev == NULL)
1185 return -ENODEV;
509e2562 1186 card = (*dev)->ml_priv;
4a71df50
FB
1187 if (!card)
1188 return -ENODEV;
1189 if ((assist_cb == NULL) || (data_cb == NULL))
1190 return -EINVAL;
1191 card->osn_info.assist_cb = assist_cb;
1192 card->osn_info.data_cb = data_cb;
1193 return 0;
1194}
1195EXPORT_SYMBOL(qeth_osn_register);
1196
1197void qeth_osn_deregister(struct net_device *dev)
1198{
1199 struct qeth_card *card;
1200
d11ba0c4 1201 QETH_DBF_TEXT(TRACE, 2, "osndereg");
4a71df50
FB
1202 if (!dev)
1203 return;
509e2562 1204 card = dev->ml_priv;
4a71df50
FB
1205 if (!card)
1206 return;
1207 card->osn_info.assist_cb = NULL;
1208 card->osn_info.data_cb = NULL;
1209 return;
1210}
1211EXPORT_SYMBOL(qeth_osn_deregister);
1212
1213module_init(qeth_l2_init);
1214module_exit(qeth_l2_exit);
1215MODULE_AUTHOR("Frank Blaschka <frank.blaschka@de.ibm.com>");
1216MODULE_DESCRIPTION("qeth layer 2 discipline");
1217MODULE_LICENSE("GPL");