aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUrsula Braun <braunu@de.ibm.com>2005-09-30 04:19:19 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-03 22:06:46 -0400
commit500f83abdc83d6bd472f3d103a9a9cd85df29a29 (patch)
tree33e6c948592c7c9b77ad8ebdc489e32ffb9c4b70
parent3c8c7b2f32c52b259daa7564fefd582146799b23 (diff)
[PATCH] s390: introducing support in qeth for new OSA CHPID type OSN
This patch introduces new feature in qeth: qeth enhancement provides the device driver support for the Communication Controller for Linux on System z9 and zSeries (CCL), which is software that enables running the Network Control Program (NCP) on a zSeries machine. The OSA CDLC support is based on a new IBM mainframe CHPID type called Open Systems Adaper for NCP (OSN). In case of OSN qeth communicates with the type-OSN OSA-card on one hand, and with the CCL-kernel-component Network Device Handler (NDH) on the other. Signed-off-by: Frank Pavlic <pavlic@de.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/s390/net/qeth.h45
-rw-r--r--drivers/s390/net/qeth_fs.h12
-rw-r--r--drivers/s390/net/qeth_main.c419
-rw-r--r--drivers/s390/net/qeth_mpc.c6
-rw-r--r--drivers/s390/net/qeth_mpc.h15
-rw-r--r--drivers/s390/net/qeth_sys.c28
6 files changed, 413 insertions, 112 deletions
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 9963479ba89f..38a2441564d7 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -275,6 +275,10 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
275 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \ 275 QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
276 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \ 276 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
277 QETH_MAX_QUEUES,0x103}, \ 277 QETH_MAX_QUEUES,0x103}, \
278 {0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \
279 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
280 QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
281 QETH_MAX_QUEUES,0}, \
278 {0,0,0,0,0,0,0,0,0}} 282 {0,0,0,0,0,0,0,0,0}}
279 283
280#define QETH_REAL_CARD 1 284#define QETH_REAL_CARD 1
@@ -363,10 +367,22 @@ struct qeth_hdr_layer2 {
363 __u8 reserved2[16]; 367 __u8 reserved2[16];
364} __attribute__ ((packed)); 368} __attribute__ ((packed));
365 369
370struct qeth_hdr_osn {
371 __u8 id;
372 __u8 reserved;
373 __u16 seq_no;
374 __u16 reserved2;
375 __u16 control_flags;
376 __u16 pdu_length;
377 __u8 reserved3[18];
378 __u32 ccid;
379} __attribute__ ((packed));
380
366struct qeth_hdr { 381struct qeth_hdr {
367 union { 382 union {
368 struct qeth_hdr_layer2 l2; 383 struct qeth_hdr_layer2 l2;
369 struct qeth_hdr_layer3 l3; 384 struct qeth_hdr_layer3 l3;
385 struct qeth_hdr_osn osn;
370 } hdr; 386 } hdr;
371} __attribute__ ((packed)); 387} __attribute__ ((packed));
372 388
@@ -413,6 +429,7 @@ enum qeth_header_ids {
413 QETH_HEADER_TYPE_LAYER3 = 0x01, 429 QETH_HEADER_TYPE_LAYER3 = 0x01,
414 QETH_HEADER_TYPE_LAYER2 = 0x02, 430 QETH_HEADER_TYPE_LAYER2 = 0x02,
415 QETH_HEADER_TYPE_TSO = 0x03, 431 QETH_HEADER_TYPE_TSO = 0x03,
432 QETH_HEADER_TYPE_OSN = 0x04,
416}; 433};
417/* flags for qeth_hdr.ext_flags */ 434/* flags for qeth_hdr.ext_flags */
418#define QETH_HDR_EXT_VLAN_FRAME 0x01 435#define QETH_HDR_EXT_VLAN_FRAME 0x01
@@ -582,7 +599,6 @@ enum qeth_card_states {
582 * Protocol versions 599 * Protocol versions
583 */ 600 */
584enum qeth_prot_versions { 601enum qeth_prot_versions {
585 QETH_PROT_SNA = 0x0001,
586 QETH_PROT_IPV4 = 0x0004, 602 QETH_PROT_IPV4 = 0x0004,
587 QETH_PROT_IPV6 = 0x0006, 603 QETH_PROT_IPV6 = 0x0006,
588}; 604};
@@ -761,6 +777,11 @@ enum qeth_threads {
761 QETH_RECOVER_THREAD = 2, 777 QETH_RECOVER_THREAD = 2,
762}; 778};
763 779
780struct qeth_osn_info {
781 int (*assist_cb)(struct net_device *dev, void *data);
782 int (*data_cb)(struct sk_buff *skb);
783};
784
764struct qeth_card { 785struct qeth_card {
765 struct list_head list; 786 struct list_head list;
766 enum qeth_card_states state; 787 enum qeth_card_states state;
@@ -803,6 +824,7 @@ struct qeth_card {
803 int use_hard_stop; 824 int use_hard_stop;
804 int (*orig_hard_header)(struct sk_buff *,struct net_device *, 825 int (*orig_hard_header)(struct sk_buff *,struct net_device *,
805 unsigned short,void *,void *,unsigned); 826 unsigned short,void *,void *,unsigned);
827 struct qeth_osn_info osn_info;
806}; 828};
807 829
808struct qeth_card_list_struct { 830struct qeth_card_list_struct {
@@ -916,10 +938,12 @@ qeth_get_hlen(__u8 link_type)
916static inline unsigned short 938static inline unsigned short
917qeth_get_netdev_flags(struct qeth_card *card) 939qeth_get_netdev_flags(struct qeth_card *card)
918{ 940{
919 if (card->options.layer2) 941 if (card->options.layer2 &&
942 (card->info.type == QETH_CARD_TYPE_OSAE))
920 return 0; 943 return 0;
921 switch (card->info.type) { 944 switch (card->info.type) {
922 case QETH_CARD_TYPE_IQD: 945 case QETH_CARD_TYPE_IQD:
946 case QETH_CARD_TYPE_OSN:
923 return IFF_NOARP; 947 return IFF_NOARP;
924#ifdef CONFIG_QETH_IPV6 948#ifdef CONFIG_QETH_IPV6
925 default: 949 default:
@@ -956,9 +980,10 @@ static inline int
956qeth_get_max_mtu_for_card(int cardtype) 980qeth_get_max_mtu_for_card(int cardtype)
957{ 981{
958 switch (cardtype) { 982 switch (cardtype) {
983
959 case QETH_CARD_TYPE_UNKNOWN: 984 case QETH_CARD_TYPE_UNKNOWN:
960 return 61440;
961 case QETH_CARD_TYPE_OSAE: 985 case QETH_CARD_TYPE_OSAE:
986 case QETH_CARD_TYPE_OSN:
962 return 61440; 987 return 61440;
963 case QETH_CARD_TYPE_IQD: 988 case QETH_CARD_TYPE_IQD:
964 return 57344; 989 return 57344;
@@ -1004,6 +1029,7 @@ qeth_mtu_is_valid(struct qeth_card * card, int mtu)
1004 case QETH_CARD_TYPE_IQD: 1029 case QETH_CARD_TYPE_IQD:
1005 return ((mtu >= 576) && 1030 return ((mtu >= 576) &&
1006 (mtu <= card->info.max_mtu + 4096 - 32)); 1031 (mtu <= card->info.max_mtu + 4096 - 32));
1032 case QETH_CARD_TYPE_OSN:
1007 case QETH_CARD_TYPE_UNKNOWN: 1033 case QETH_CARD_TYPE_UNKNOWN:
1008 default: 1034 default:
1009 return 1; 1035 return 1;
@@ -1015,6 +1041,7 @@ qeth_get_arphdr_type(int cardtype, int linktype)
1015{ 1041{
1016 switch (cardtype) { 1042 switch (cardtype) {
1017 case QETH_CARD_TYPE_OSAE: 1043 case QETH_CARD_TYPE_OSAE:
1044 case QETH_CARD_TYPE_OSN:
1018 switch (linktype) { 1045 switch (linktype) {
1019 case QETH_LINK_TYPE_LANE_TR: 1046 case QETH_LINK_TYPE_LANE_TR:
1020 case QETH_LINK_TYPE_HSTR: 1047 case QETH_LINK_TYPE_HSTR:
@@ -1182,4 +1209,16 @@ qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
1182extern void 1209extern void
1183qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int); 1210qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
1184 1211
1212extern int
1213qeth_osn_assist(struct net_device *, void *, int);
1214
1215extern int
1216qeth_osn_register(unsigned char *read_dev_no,
1217 struct net_device **,
1218 int (*assist_cb)(struct net_device *, void *),
1219 int (*data_cb)(struct sk_buff *));
1220
1221extern void
1222qeth_osn_deregister(struct net_device *);
1223
1185#endif /* __QETH_H__ */ 1224#endif /* __QETH_H__ */
diff --git a/drivers/s390/net/qeth_fs.h b/drivers/s390/net/qeth_fs.h
index 5c9a51ce91b6..c0b4c8d82c45 100644
--- a/drivers/s390/net/qeth_fs.h
+++ b/drivers/s390/net/qeth_fs.h
@@ -12,7 +12,7 @@
12#ifndef __QETH_FS_H__ 12#ifndef __QETH_FS_H__
13#define __QETH_FS_H__ 13#define __QETH_FS_H__
14 14
15#define VERSION_QETH_FS_H "$Revision: 1.9 $" 15#define VERSION_QETH_FS_H "$Revision: 1.10 $"
16 16
17extern const char *VERSION_QETH_PROC_C; 17extern const char *VERSION_QETH_PROC_C;
18extern const char *VERSION_QETH_SYS_C; 18extern const char *VERSION_QETH_SYS_C;
@@ -43,6 +43,12 @@ extern void
43qeth_remove_device_attributes(struct device *dev); 43qeth_remove_device_attributes(struct device *dev);
44 44
45extern int 45extern int
46qeth_create_device_attributes_osn(struct device *dev);
47
48extern void
49qeth_remove_device_attributes_osn(struct device *dev);
50
51extern int
46qeth_create_driver_attributes(void); 52qeth_create_driver_attributes(void);
47 53
48extern void 54extern void
@@ -108,6 +114,8 @@ qeth_get_cardname(struct qeth_card *card)
108 return " OSD Express"; 114 return " OSD Express";
109 case QETH_CARD_TYPE_IQD: 115 case QETH_CARD_TYPE_IQD:
110 return " HiperSockets"; 116 return " HiperSockets";
117 case QETH_CARD_TYPE_OSN:
118 return " OSN QDIO";
111 default: 119 default:
112 return " unknown"; 120 return " unknown";
113 } 121 }
@@ -153,6 +161,8 @@ qeth_get_cardname_short(struct qeth_card *card)
153 } 161 }
154 case QETH_CARD_TYPE_IQD: 162 case QETH_CARD_TYPE_IQD:
155 return "HiperSockets"; 163 return "HiperSockets";
164 case QETH_CARD_TYPE_OSN:
165 return "OSN";
156 default: 166 default:
157 return "unknown"; 167 return "unknown";
158 } 168 }
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index bd28e2438d7f..692003c9f896 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -196,7 +196,6 @@ qeth_notifier_register(struct task_struct *p, int signum)
196{ 196{
197 struct qeth_notify_list_struct *n_entry; 197 struct qeth_notify_list_struct *n_entry;
198 198
199
200 /*check first if entry already exists*/ 199 /*check first if entry already exists*/
201 spin_lock(&qeth_notify_lock); 200 spin_lock(&qeth_notify_lock);
202 list_for_each_entry(n_entry, &qeth_notify_list, list) { 201 list_for_each_entry(n_entry, &qeth_notify_list, list) {
@@ -1024,7 +1023,10 @@ qeth_set_intial_options(struct qeth_card *card)
1024 card->options.fake_broadcast = 0; 1023 card->options.fake_broadcast = 0;
1025 card->options.add_hhlen = DEFAULT_ADD_HHLEN; 1024 card->options.add_hhlen = DEFAULT_ADD_HHLEN;
1026 card->options.fake_ll = 0; 1025 card->options.fake_ll = 0;
1027 card->options.layer2 = 0; 1026 if (card->info.type == QETH_CARD_TYPE_OSN)
1027 card->options.layer2 = 1;
1028 else
1029 card->options.layer2 = 0;
1028} 1030}
1029 1031
1030/** 1032/**
@@ -1113,19 +1115,20 @@ qeth_determine_card_type(struct qeth_card *card)
1113 1115
1114 QETH_DBF_TEXT(setup, 2, "detcdtyp"); 1116 QETH_DBF_TEXT(setup, 2, "detcdtyp");
1115 1117
1118 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
1119 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
1116 while (known_devices[i][4]) { 1120 while (known_devices[i][4]) {
1117 if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) && 1121 if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
1118 (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) { 1122 (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
1119 card->info.type = known_devices[i][4]; 1123 card->info.type = known_devices[i][4];
1124 card->qdio.no_out_queues = known_devices[i][8];
1125 card->info.is_multicast_different = known_devices[i][9];
1120 if (is_1920_device(card)) { 1126 if (is_1920_device(card)) {
1121 PRINT_INFO("Priority Queueing not able " 1127 PRINT_INFO("Priority Queueing not able "
1122 "due to hardware limitations!\n"); 1128 "due to hardware limitations!\n");
1123 card->qdio.no_out_queues = 1; 1129 card->qdio.no_out_queues = 1;
1124 card->qdio.default_out_queue = 0; 1130 card->qdio.default_out_queue = 0;
1125 } else { 1131 }
1126 card->qdio.no_out_queues = known_devices[i][8];
1127 }
1128 card->info.is_multicast_different = known_devices[i][9];
1129 return 0; 1132 return 0;
1130 } 1133 }
1131 i++; 1134 i++;
@@ -1149,6 +1152,8 @@ qeth_probe_device(struct ccwgroup_device *gdev)
1149 if (!get_device(dev)) 1152 if (!get_device(dev))
1150 return -ENODEV; 1153 return -ENODEV;
1151 1154
1155 QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
1156
1152 card = qeth_alloc_card(); 1157 card = qeth_alloc_card();
1153 if (!card) { 1158 if (!card) {
1154 put_device(dev); 1159 put_device(dev);
@@ -1158,28 +1163,27 @@ qeth_probe_device(struct ccwgroup_device *gdev)
1158 card->read.ccwdev = gdev->cdev[0]; 1163 card->read.ccwdev = gdev->cdev[0];
1159 card->write.ccwdev = gdev->cdev[1]; 1164 card->write.ccwdev = gdev->cdev[1];
1160 card->data.ccwdev = gdev->cdev[2]; 1165 card->data.ccwdev = gdev->cdev[2];
1161
1162 if ((rc = qeth_setup_card(card))){
1163 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
1164 put_device(dev);
1165 qeth_free_card(card);
1166 return rc;
1167 }
1168 gdev->dev.driver_data = card; 1166 gdev->dev.driver_data = card;
1169 card->gdev = gdev; 1167 card->gdev = gdev;
1170 gdev->cdev[0]->handler = qeth_irq; 1168 gdev->cdev[0]->handler = qeth_irq;
1171 gdev->cdev[1]->handler = qeth_irq; 1169 gdev->cdev[1]->handler = qeth_irq;
1172 gdev->cdev[2]->handler = qeth_irq; 1170 gdev->cdev[2]->handler = qeth_irq;
1173 1171
1174 rc = qeth_create_device_attributes(dev); 1172 if ((rc = qeth_determine_card_type(card))){
1175 if (rc) { 1173 PRINT_WARN("%s: not a valid card type\n", __func__);
1174 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
1175 put_device(dev);
1176 qeth_free_card(card);
1177 return rc;
1178 }
1179 if ((rc = qeth_setup_card(card))){
1180 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
1176 put_device(dev); 1181 put_device(dev);
1177 qeth_free_card(card); 1182 qeth_free_card(card);
1178 return rc; 1183 return rc;
1179 } 1184 }
1180 if ((rc = qeth_determine_card_type(card))){ 1185 rc = qeth_create_device_attributes(dev);
1181 PRINT_WARN("%s: not a valid card type\n", __func__); 1186 if (rc) {
1182 QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
1183 put_device(dev); 1187 put_device(dev);
1184 qeth_free_card(card); 1188 qeth_free_card(card);
1185 return rc; 1189 return rc;
@@ -1660,6 +1664,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
1660 netif_carrier_on(card->dev); 1664 netif_carrier_on(card->dev);
1661 qeth_schedule_recovery(card); 1665 qeth_schedule_recovery(card);
1662 return NULL; 1666 return NULL;
1667 case IPA_CMD_MODCCID:
1668 return cmd;
1663 case IPA_CMD_REGISTER_LOCAL_ADDR: 1669 case IPA_CMD_REGISTER_LOCAL_ADDR:
1664 QETH_DBF_TEXT(trace,3, "irla"); 1670 QETH_DBF_TEXT(trace,3, "irla");
1665 break; 1671 break;
@@ -1721,6 +1727,14 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
1721 cmd = qeth_check_ipa_data(card, iob); 1727 cmd = qeth_check_ipa_data(card, iob);
1722 if ((cmd == NULL) && (card->state != CARD_STATE_DOWN)) 1728 if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
1723 goto out; 1729 goto out;
1730 /*in case of OSN : check if cmd is set */
1731 if (card->info.type == QETH_CARD_TYPE_OSN &&
1732 cmd &&
1733 cmd->hdr.command != IPA_CMD_STARTLAN &&
1734 card->osn_info.assist_cb != NULL) {
1735 card->osn_info.assist_cb(card->dev, cmd);
1736 goto out;
1737 }
1724 1738
1725 spin_lock_irqsave(&card->lock, flags); 1739 spin_lock_irqsave(&card->lock, flags);
1726 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) { 1740 list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
@@ -1737,8 +1751,7 @@ qeth_send_control_data_cb(struct qeth_channel *channel,
1737 keep_reply = reply->callback(card, 1751 keep_reply = reply->callback(card,
1738 reply, 1752 reply,
1739 (unsigned long)cmd); 1753 (unsigned long)cmd);
1740 } 1754 } else
1741 else
1742 keep_reply = reply->callback(card, 1755 keep_reply = reply->callback(card,
1743 reply, 1756 reply,
1744 (unsigned long)iob); 1757 (unsigned long)iob);
@@ -1768,6 +1781,24 @@ out:
1768 qeth_release_buffer(channel,iob); 1781 qeth_release_buffer(channel,iob);
1769} 1782}
1770 1783
1784static inline void
1785qeth_prepare_control_data(struct qeth_card *card, int len,
1786struct qeth_cmd_buffer *iob)
1787{
1788 qeth_setup_ccw(&card->write,iob->data,len);
1789 iob->callback = qeth_release_buffer;
1790
1791 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1792 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1793 card->seqno.trans_hdr++;
1794 memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
1795 &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
1796 card->seqno.pdu_hdr++;
1797 memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
1798 &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1799 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1800}
1801
1771static int 1802static int
1772qeth_send_control_data(struct qeth_card *card, int len, 1803qeth_send_control_data(struct qeth_card *card, int len,
1773 struct qeth_cmd_buffer *iob, 1804 struct qeth_cmd_buffer *iob,
@@ -1778,24 +1809,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
1778{ 1809{
1779 int rc; 1810 int rc;
1780 unsigned long flags; 1811 unsigned long flags;
1781 struct qeth_reply *reply; 1812 struct qeth_reply *reply = NULL;
1782 struct timer_list timer; 1813 struct timer_list timer;
1783 1814
1784 QETH_DBF_TEXT(trace, 2, "sendctl"); 1815 QETH_DBF_TEXT(trace, 2, "sendctl");
1785 1816
1786 qeth_setup_ccw(&card->write,iob->data,len);
1787
1788 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1789 &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1790 card->seqno.trans_hdr++;
1791
1792 memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
1793 &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
1794 card->seqno.pdu_hdr++;
1795 memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
1796 &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1797 iob->callback = qeth_release_buffer;
1798
1799 reply = qeth_alloc_reply(card); 1817 reply = qeth_alloc_reply(card);
1800 if (!reply) { 1818 if (!reply) {
1801 PRINT_WARN("Could no alloc qeth_reply!\n"); 1819 PRINT_WARN("Could no alloc qeth_reply!\n");
@@ -1810,10 +1828,6 @@ qeth_send_control_data(struct qeth_card *card, int len,
1810 init_timer(&timer); 1828 init_timer(&timer);
1811 timer.function = qeth_cmd_timeout; 1829 timer.function = qeth_cmd_timeout;
1812 timer.data = (unsigned long) reply; 1830 timer.data = (unsigned long) reply;
1813 if (IS_IPA(iob->data))
1814 timer.expires = jiffies + QETH_IPA_TIMEOUT;
1815 else
1816 timer.expires = jiffies + QETH_TIMEOUT;
1817 init_waitqueue_head(&reply->wait_q); 1831 init_waitqueue_head(&reply->wait_q);
1818 spin_lock_irqsave(&card->lock, flags); 1832 spin_lock_irqsave(&card->lock, flags);
1819 list_add_tail(&reply->list, &card->cmd_waiter_list); 1833 list_add_tail(&reply->list, &card->cmd_waiter_list);
@@ -1821,6 +1835,11 @@ qeth_send_control_data(struct qeth_card *card, int len,
1821 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN); 1835 QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
1822 wait_event(card->wait_q, 1836 wait_event(card->wait_q,
1823 atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0); 1837 atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
1838 qeth_prepare_control_data(card, len, iob);
1839 if (IS_IPA(iob->data))
1840 timer.expires = jiffies + QETH_IPA_TIMEOUT;
1841 else
1842 timer.expires = jiffies + QETH_TIMEOUT;
1824 QETH_DBF_TEXT(trace, 6, "noirqpnd"); 1843 QETH_DBF_TEXT(trace, 6, "noirqpnd");
1825 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags); 1844 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1826 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw, 1845 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
@@ -1848,6 +1867,62 @@ qeth_send_control_data(struct qeth_card *card, int len,
1848} 1867}
1849 1868
1850static int 1869static int
1870qeth_osn_send_control_data(struct qeth_card *card, int len,
1871 struct qeth_cmd_buffer *iob)
1872{
1873 unsigned long flags;
1874 int rc = 0;
1875
1876 QETH_DBF_TEXT(trace, 5, "osndctrd");
1877
1878 wait_event(card->wait_q,
1879 atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
1880 qeth_prepare_control_data(card, len, iob);
1881 QETH_DBF_TEXT(trace, 6, "osnoirqp");
1882 spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
1883 rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
1884 (addr_t) iob, 0, 0);
1885 spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
1886 if (rc){
1887 PRINT_WARN("qeth_osn_send_control_data: "
1888 "ccw_device_start rc = %i\n", rc);
1889 QETH_DBF_TEXT_(trace, 2, " err%d", rc);
1890 qeth_release_buffer(iob->channel, iob);
1891 atomic_set(&card->write.irq_pending, 0);
1892 wake_up(&card->wait_q);
1893 }
1894 return rc;
1895}
1896
1897static inline void
1898qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1899 char prot_type)
1900{
1901 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
1902 memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
1903 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
1904 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
1905}
1906
1907static int
1908qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1909 int data_len)
1910{
1911 u16 s1, s2;
1912
1913QETH_DBF_TEXT(trace,4,"osndipa");
1914
1915 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
1916 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
1917 s2 = (u16)data_len;
1918 memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
1919 memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
1920 memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
1921 memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
1922 return qeth_osn_send_control_data(card, s1, iob);
1923}
1924
1925static int
1851qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, 1926qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1852 int (*reply_cb) 1927 int (*reply_cb)
1853 (struct qeth_card *,struct qeth_reply*, unsigned long), 1928 (struct qeth_card *,struct qeth_reply*, unsigned long),
@@ -1858,17 +1933,14 @@ qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1858 1933
1859 QETH_DBF_TEXT(trace,4,"sendipa"); 1934 QETH_DBF_TEXT(trace,4,"sendipa");
1860 1935
1861 memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
1862
1863 if (card->options.layer2) 1936 if (card->options.layer2)
1864 prot_type = QETH_PROT_LAYER2; 1937 if (card->info.type == QETH_CARD_TYPE_OSN)
1938 prot_type = QETH_PROT_OSN2;
1939 else
1940 prot_type = QETH_PROT_LAYER2;
1865 else 1941 else
1866 prot_type = QETH_PROT_TCPIP; 1942 prot_type = QETH_PROT_TCPIP;
1867 1943 qeth_prepare_ipa_cmd(card,iob,prot_type);
1868 memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
1869 memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
1870 &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
1871
1872 rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob, 1944 rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
1873 reply_cb, reply_param); 1945 reply_cb, reply_param);
1874 return rc; 1946 return rc;
@@ -2010,7 +2082,10 @@ qeth_ulp_enable(struct qeth_card *card)
2010 *(QETH_ULP_ENABLE_LINKNUM(iob->data)) = 2082 *(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
2011 (__u8) card->info.portno; 2083 (__u8) card->info.portno;
2012 if (card->options.layer2) 2084 if (card->options.layer2)
2013 prot_type = QETH_PROT_LAYER2; 2085 if (card->info.type == QETH_CARD_TYPE_OSN)
2086 prot_type = QETH_PROT_OSN2;
2087 else
2088 prot_type = QETH_PROT_LAYER2;
2014 else 2089 else
2015 prot_type = QETH_PROT_TCPIP; 2090 prot_type = QETH_PROT_TCPIP;
2016 2091
@@ -2100,15 +2175,21 @@ qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
2100} 2175}
2101 2176
2102static inline struct sk_buff * 2177static inline struct sk_buff *
2103qeth_get_skb(unsigned int length) 2178qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
2104{ 2179{
2105 struct sk_buff* skb; 2180 struct sk_buff* skb;
2181 int add_len;
2182
2183 add_len = 0;
2184 if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
2185 add_len = sizeof(struct qeth_hdr);
2106#ifdef CONFIG_QETH_VLAN 2186#ifdef CONFIG_QETH_VLAN
2107 if ((skb = dev_alloc_skb(length + VLAN_HLEN))) 2187 else
2108 skb_reserve(skb, VLAN_HLEN); 2188 add_len = VLAN_HLEN;
2109#else
2110 skb = dev_alloc_skb(length);
2111#endif 2189#endif
2190 skb = dev_alloc_skb(length + add_len);
2191 if (skb && add_len)
2192 skb_reserve(skb, add_len);
2112 return skb; 2193 return skb;
2113} 2194}
2114 2195
@@ -2138,7 +2219,10 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2138 2219
2139 offset += sizeof(struct qeth_hdr); 2220 offset += sizeof(struct qeth_hdr);
2140 if (card->options.layer2) 2221 if (card->options.layer2)
2141 skb_len = (*hdr)->hdr.l2.pkt_length; 2222 if (card->info.type == QETH_CARD_TYPE_OSN)
2223 skb_len = (*hdr)->hdr.osn.pdu_length;
2224 else
2225 skb_len = (*hdr)->hdr.l2.pkt_length;
2142 else 2226 else
2143 skb_len = (*hdr)->hdr.l3.length; 2227 skb_len = (*hdr)->hdr.l3.length;
2144 2228
@@ -2146,15 +2230,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2146 return NULL; 2230 return NULL;
2147 if (card->options.fake_ll){ 2231 if (card->options.fake_ll){
2148 if(card->dev->type == ARPHRD_IEEE802_TR){ 2232 if(card->dev->type == ARPHRD_IEEE802_TR){
2149 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR))) 2233 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR, *hdr)))
2150 goto no_mem; 2234 goto no_mem;
2151 skb_reserve(skb,QETH_FAKE_LL_LEN_TR); 2235 skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
2152 } else { 2236 } else {
2153 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH))) 2237 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH, *hdr)))
2154 goto no_mem; 2238 goto no_mem;
2155 skb_reserve(skb,QETH_FAKE_LL_LEN_ETH); 2239 skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
2156 } 2240 }
2157 } else if (!(skb = qeth_get_skb(skb_len))) 2241 } else if (!(skb = qeth_get_skb(skb_len, *hdr)))
2158 goto no_mem; 2242 goto no_mem;
2159 data_ptr = element->addr + offset; 2243 data_ptr = element->addr + offset;
2160 while (skb_len) { 2244 while (skb_len) {
@@ -2453,8 +2537,12 @@ qeth_process_inbound_buffer(struct qeth_card *card,
2453 skb->dev = card->dev; 2537 skb->dev = card->dev;
2454 if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) 2538 if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
2455 vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); 2539 vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
2456 else 2540 else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
2457 qeth_rebuild_skb(card, skb, hdr); 2541 qeth_rebuild_skb(card, skb, hdr);
2542 else { /*in case of OSN*/
2543 skb_push(skb, sizeof(struct qeth_hdr));
2544 memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
2545 }
2458 /* is device UP ? */ 2546 /* is device UP ? */
2459 if (!(card->dev->flags & IFF_UP)){ 2547 if (!(card->dev->flags & IFF_UP)){
2460 dev_kfree_skb_any(skb); 2548 dev_kfree_skb_any(skb);
@@ -2465,7 +2553,10 @@ qeth_process_inbound_buffer(struct qeth_card *card,
2465 vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag); 2553 vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
2466 else 2554 else
2467#endif 2555#endif
2468 rxrc = netif_rx(skb); 2556 if (card->info.type == QETH_CARD_TYPE_OSN)
2557 rxrc = card->osn_info.data_cb(skb);
2558 else
2559 rxrc = netif_rx(skb);
2469 card->dev->last_rx = jiffies; 2560 card->dev->last_rx = jiffies;
2470 card->stats.rx_packets++; 2561 card->stats.rx_packets++;
2471 card->stats.rx_bytes += skb->len; 2562 card->stats.rx_bytes += skb->len;
@@ -3150,8 +3241,6 @@ qeth_init_qdio_info(struct qeth_card *card)
3150 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); 3241 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
3151 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); 3242 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
3152 /* outbound */ 3243 /* outbound */
3153 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
3154 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
3155} 3244}
3156 3245
3157static int 3246static int
@@ -3466,7 +3555,7 @@ qeth_mpc_initialize(struct qeth_card *card)
3466 3555
3467 return 0; 3556 return 0;
3468out_qdio: 3557out_qdio:
3469 qeth_qdio_clear_card(card, card->info.type==QETH_CARD_TYPE_OSAE); 3558 qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
3470 return rc; 3559 return rc;
3471} 3560}
3472 3561
@@ -3491,6 +3580,9 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
3491 case QETH_CARD_TYPE_IQD: 3580 case QETH_CARD_TYPE_IQD:
3492 dev = alloc_netdev(0, "hsi%d", ether_setup); 3581 dev = alloc_netdev(0, "hsi%d", ether_setup);
3493 break; 3582 break;
3583 case QETH_CARD_TYPE_OSN:
3584 dev = alloc_netdev(0, "osn%d", ether_setup);
3585 break;
3494 default: 3586 default:
3495 dev = alloc_etherdev(0); 3587 dev = alloc_etherdev(0);
3496 } 3588 }
@@ -3655,7 +3747,8 @@ qeth_open(struct net_device *dev)
3655 if (card->state != CARD_STATE_SOFTSETUP) 3747 if (card->state != CARD_STATE_SOFTSETUP)
3656 return -ENODEV; 3748 return -ENODEV;
3657 3749
3658 if ( (card->options.layer2) && 3750 if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
3751 (card->options.layer2) &&
3659 (!card->info.layer2_mac_registered)) { 3752 (!card->info.layer2_mac_registered)) {
3660 QETH_DBF_TEXT(trace,4,"nomacadr"); 3753 QETH_DBF_TEXT(trace,4,"nomacadr");
3661 return -EPERM; 3754 return -EPERM;
@@ -3693,6 +3786,9 @@ qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
3693{ 3786{
3694 int cast_type = RTN_UNSPEC; 3787 int cast_type = RTN_UNSPEC;
3695 3788
3789 if (card->info.type == QETH_CARD_TYPE_OSN)
3790 return cast_type;
3791
3696 if (skb->dst && skb->dst->neighbour){ 3792 if (skb->dst && skb->dst->neighbour){
3697 cast_type = skb->dst->neighbour->type; 3793 cast_type = skb->dst->neighbour->type;
3698 if ((cast_type == RTN_BROADCAST) || 3794 if ((cast_type == RTN_BROADCAST) ||
@@ -3782,13 +3878,16 @@ static inline int
3782qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, 3878qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
3783 struct qeth_hdr **hdr, int ipv) 3879 struct qeth_hdr **hdr, int ipv)
3784{ 3880{
3785 int rc; 3881 int rc = 0;
3786#ifdef CONFIG_QETH_VLAN 3882#ifdef CONFIG_QETH_VLAN
3787 u16 *tag; 3883 u16 *tag;
3788#endif 3884#endif
3789 3885
3790 QETH_DBF_TEXT(trace, 6, "prepskb"); 3886 QETH_DBF_TEXT(trace, 6, "prepskb");
3791 3887 if (card->info.type == QETH_CARD_TYPE_OSN) {
3888 *hdr = (struct qeth_hdr *)(*skb)->data;
3889 return rc;
3890 }
3792 rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); 3891 rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
3793 if (rc) 3892 if (rc)
3794 return rc; 3893 return rc;
@@ -4291,8 +4390,14 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4291 } 4390 }
4292 } 4391 }
4293 } 4392 }
4393 if ((card->info.type == QETH_CARD_TYPE_OSN) &&
4394 (skb->protocol == htons(ETH_P_IPV6))) {
4395 dev_kfree_skb_any(skb);
4396 return 0;
4397 }
4294 cast_type = qeth_get_cast_type(card, skb); 4398 cast_type = qeth_get_cast_type(card, skb);
4295 if ((cast_type == RTN_BROADCAST) && (card->info.broadcast_capable == 0)){ 4399 if ((cast_type == RTN_BROADCAST) &&
4400 (card->info.broadcast_capable == 0)){
4296 card->stats.tx_dropped++; 4401 card->stats.tx_dropped++;
4297 card->stats.tx_errors++; 4402 card->stats.tx_errors++;
4298 dev_kfree_skb_any(skb); 4403 dev_kfree_skb_any(skb);
@@ -4320,7 +4425,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4320 QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); 4425 QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
4321 return rc; 4426 return rc;
4322 } 4427 }
4323 qeth_fill_header(card, hdr, skb, ipv, cast_type); 4428 if (card->info.type != QETH_CARD_TYPE_OSN)
4429 qeth_fill_header(card, hdr, skb, ipv, cast_type);
4324 } 4430 }
4325 4431
4326 if (large_send == QETH_LARGE_SEND_EDDP) { 4432 if (large_send == QETH_LARGE_SEND_EDDP) {
@@ -4381,6 +4487,7 @@ qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
4381 case MII_BMCR: /* Basic mode control register */ 4487 case MII_BMCR: /* Basic mode control register */
4382 rc = BMCR_FULLDPLX; 4488 rc = BMCR_FULLDPLX;
4383 if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&& 4489 if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
4490 (card->info.link_type != QETH_LINK_TYPE_OSN) &&
4384 (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH)) 4491 (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
4385 rc |= BMCR_SPEED100; 4492 rc |= BMCR_SPEED100;
4386 break; 4493 break;
@@ -5004,6 +5111,9 @@ qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5004 (card->state != CARD_STATE_SOFTSETUP)) 5111 (card->state != CARD_STATE_SOFTSETUP))
5005 return -ENODEV; 5112 return -ENODEV;
5006 5113
5114 if (card->info.type == QETH_CARD_TYPE_OSN)
5115 return -EPERM;
5116
5007 switch (cmd){ 5117 switch (cmd){
5008 case SIOC_QETH_ARP_SET_NO_ENTRIES: 5118 case SIOC_QETH_ARP_SET_NO_ENTRIES:
5009 if ( !capable(CAP_NET_ADMIN) || 5119 if ( !capable(CAP_NET_ADMIN) ||
@@ -5329,6 +5439,9 @@ qeth_set_multicast_list(struct net_device *dev)
5329{ 5439{
5330 struct qeth_card *card = (struct qeth_card *) dev->priv; 5440 struct qeth_card *card = (struct qeth_card *) dev->priv;
5331 5441
5442 if (card->info.type == QETH_CARD_TYPE_OSN)
5443 return ;
5444
5332 QETH_DBF_TEXT(trace,3,"setmulti"); 5445 QETH_DBF_TEXT(trace,3,"setmulti");
5333 qeth_delete_mc_addresses(card); 5446 qeth_delete_mc_addresses(card);
5334 qeth_add_multicast_ipv4(card); 5447 qeth_add_multicast_ipv4(card);
@@ -5370,6 +5483,94 @@ qeth_get_addr_buffer(enum qeth_prot_versions prot)
5370 return addr; 5483 return addr;
5371} 5484}
5372 5485
5486int
5487qeth_osn_assist(struct net_device *dev,
5488 void *data,
5489 int data_len)
5490{
5491 struct qeth_cmd_buffer *iob;
5492 struct qeth_card *card;
5493 int rc;
5494
5495 QETH_DBF_TEXT(trace, 2, "osnsdmc");
5496 if (!dev)
5497 return -ENODEV;
5498 card = (struct qeth_card *)dev->priv;
5499 if (!card)
5500 return -ENODEV;
5501 if ((card->state != CARD_STATE_UP) &&
5502 (card->state != CARD_STATE_SOFTSETUP))
5503 return -ENODEV;
5504 iob = qeth_wait_for_buffer(&card->write);
5505 memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
5506 rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
5507 return rc;
5508}
5509
5510static struct net_device *
5511qeth_netdev_by_devno(unsigned char *read_dev_no)
5512{
5513 struct qeth_card *card;
5514 struct net_device *ndev;
5515 unsigned char *readno;
5516 __u16 temp_dev_no, card_dev_no;
5517 char *endp;
5518 unsigned long flags;
5519
5520 ndev = NULL;
5521 memcpy(&temp_dev_no, read_dev_no, 2);
5522 read_lock_irqsave(&qeth_card_list.rwlock, flags);
5523 list_for_each_entry(card, &qeth_card_list.list, list) {
5524 readno = CARD_RDEV_ID(card);
5525 readno += (strlen(readno) - 4);
5526 card_dev_no = simple_strtoul(readno, &endp, 16);
5527 if (card_dev_no == temp_dev_no) {
5528 ndev = card->dev;
5529 break;
5530 }
5531 }
5532 read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
5533 return ndev;
5534}
5535
5536int
5537qeth_osn_register(unsigned char *read_dev_no,
5538 struct net_device **dev,
5539 int (*assist_cb)(struct net_device *, void *),
5540 int (*data_cb)(struct sk_buff *))
5541{
5542 struct qeth_card * card;
5543
5544 QETH_DBF_TEXT(trace, 2, "osnreg");
5545 *dev = qeth_netdev_by_devno(read_dev_no);
5546 if (*dev == NULL)
5547 return -ENODEV;
5548 card = (struct qeth_card *)(*dev)->priv;
5549 if (!card)
5550 return -ENODEV;
5551 if ((assist_cb == NULL) || (data_cb == NULL))
5552 return -EINVAL;
5553 card->osn_info.assist_cb = assist_cb;
5554 card->osn_info.data_cb = data_cb;
5555 return 0;
5556}
5557
5558void
5559qeth_osn_deregister(struct net_device * dev)
5560{
5561 struct qeth_card *card;
5562
5563 QETH_DBF_TEXT(trace, 2, "osndereg");
5564 if (!dev)
5565 return;
5566 card = (struct qeth_card *)dev->priv;
5567 if (!card)
5568 return;
5569 card->osn_info.assist_cb = NULL;
5570 card->osn_info.data_cb = NULL;
5571 return;
5572}
5573
5373static void 5574static void
5374qeth_delete_mc_addresses(struct qeth_card *card) 5575qeth_delete_mc_addresses(struct qeth_card *card)
5375{ 5576{
@@ -5700,6 +5901,12 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
5700 QETH_DBF_TEXT(trace, 3, "setmcLY3"); 5901 QETH_DBF_TEXT(trace, 3, "setmcLY3");
5701 return -EOPNOTSUPP; 5902 return -EOPNOTSUPP;
5702 } 5903 }
5904 if (card->info.type == QETH_CARD_TYPE_OSN) {
5905 PRINT_WARN("Setting MAC address on %s is not supported.\n",
5906 dev->name);
5907 QETH_DBF_TEXT(trace, 3, "setmcOSN");
5908 return -EOPNOTSUPP;
5909 }
5703 QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card)); 5910 QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
5704 QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN); 5911 QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
5705 rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]); 5912 rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
@@ -6076,9 +6283,8 @@ qeth_netdev_init(struct net_device *dev)
6076 qeth_get_hlen(card->info.link_type) + card->options.add_hhlen; 6283 qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
6077 dev->addr_len = OSA_ADDR_LEN; 6284 dev->addr_len = OSA_ADDR_LEN;
6078 dev->mtu = card->info.initial_mtu; 6285 dev->mtu = card->info.initial_mtu;
6079 6286 if (card->info.type != QETH_CARD_TYPE_OSN)
6080 SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops); 6287 SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
6081
6082 SET_MODULE_OWNER(dev); 6288 SET_MODULE_OWNER(dev);
6083 return 0; 6289 return 0;
6084} 6290}
@@ -6095,6 +6301,7 @@ qeth_init_func_level(struct qeth_card *card)
6095 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT; 6301 QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
6096 } else { 6302 } else {
6097 if (card->info.type == QETH_CARD_TYPE_IQD) 6303 if (card->info.type == QETH_CARD_TYPE_IQD)
6304 /*FIXME:why do we have same values for dis and ena for osae??? */
6098 card->info.func_level = 6305 card->info.func_level =
6099 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT; 6306 QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
6100 else 6307 else
@@ -6124,7 +6331,7 @@ retry:
6124 ccw_device_set_online(CARD_WDEV(card)); 6331 ccw_device_set_online(CARD_WDEV(card));
6125 ccw_device_set_online(CARD_DDEV(card)); 6332 ccw_device_set_online(CARD_DDEV(card));
6126 } 6333 }
6127 rc = qeth_qdio_clear_card(card,card->info.type==QETH_CARD_TYPE_OSAE); 6334 rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
6128 if (rc == -ERESTARTSYS) { 6335 if (rc == -ERESTARTSYS) {
6129 QETH_DBF_TEXT(setup, 2, "break1"); 6336 QETH_DBF_TEXT(setup, 2, "break1");
6130 return rc; 6337 return rc;
@@ -6176,8 +6383,8 @@ retry:
6176 card->dev = qeth_get_netdevice(card->info.type, 6383 card->dev = qeth_get_netdevice(card->info.type,
6177 card->info.link_type); 6384 card->info.link_type);
6178 if (!card->dev){ 6385 if (!card->dev){
6179 qeth_qdio_clear_card(card, card->info.type == 6386 qeth_qdio_clear_card(card, card->info.type !=
6180 QETH_CARD_TYPE_OSAE); 6387 QETH_CARD_TYPE_IQD);
6181 rc = -ENODEV; 6388 rc = -ENODEV;
6182 QETH_DBF_TEXT_(setup, 2, "6err%d", rc); 6389 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
6183 goto out; 6390 goto out;
@@ -7084,6 +7291,8 @@ qeth_softsetup_card(struct qeth_card *card)
7084 return rc; 7291 return rc;
7085 } else 7292 } else
7086 card->lan_online = 1; 7293 card->lan_online = 1;
7294 if (card->info.type==QETH_CARD_TYPE_OSN)
7295 goto out;
7087 if (card->options.layer2) { 7296 if (card->options.layer2) {
7088 card->dev->features |= 7297 card->dev->features |=
7089 NETIF_F_HW_VLAN_FILTER | 7298 NETIF_F_HW_VLAN_FILTER |
@@ -7255,7 +7464,8 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode)
7255 if (card->read.state == CH_STATE_UP && 7464 if (card->read.state == CH_STATE_UP &&
7256 card->write.state == CH_STATE_UP && 7465 card->write.state == CH_STATE_UP &&
7257 (card->state == CARD_STATE_UP)) { 7466 (card->state == CARD_STATE_UP)) {
7258 if(recovery_mode) { 7467 if (recovery_mode &&
7468 card->info.type != QETH_CARD_TYPE_OSN) {
7259 qeth_stop(card->dev); 7469 qeth_stop(card->dev);
7260 } else { 7470 } else {
7261 rtnl_lock(); 7471 rtnl_lock();
@@ -7437,7 +7647,8 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
7437{ 7647{
7438 QETH_DBF_TEXT(setup ,2, "startag"); 7648 QETH_DBF_TEXT(setup ,2, "startag");
7439 7649
7440 if(recovery_mode) { 7650 if (recovery_mode &&
7651 card->info.type != QETH_CARD_TYPE_OSN) {
7441 qeth_open(card->dev); 7652 qeth_open(card->dev);
7442 } else { 7653 } else {
7443 rtnl_lock(); 7654 rtnl_lock();
@@ -7469,33 +7680,36 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
7469static void qeth_make_parameters_consistent(struct qeth_card *card) 7680static void qeth_make_parameters_consistent(struct qeth_card *card)
7470{ 7681{
7471 7682
7472 if (card->options.layer2) { 7683 if (card->options.layer2 == 0)
7473 if (card->info.type == QETH_CARD_TYPE_IQD) { 7684 return;
7474 PRINT_ERR("Device %s does not support " \ 7685 if (card->info.type == QETH_CARD_TYPE_OSN)
7475 "layer 2 functionality. " \ 7686 return;
7476 "Ignoring layer2 option.\n",CARD_BUS_ID(card)); 7687 if (card->info.type == QETH_CARD_TYPE_IQD) {
7477 } 7688 PRINT_ERR("Device %s does not support layer 2 functionality." \
7478 IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER, 7689 " Ignoring layer2 option.\n",CARD_BUS_ID(card));
7479 "Routing options are"); 7690 card->options.layer2 = 0;
7691 return;
7692 }
7693 IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
7694 "Routing options are");
7480#ifdef CONFIG_QETH_IPV6 7695#ifdef CONFIG_QETH_IPV6
7481 IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER, 7696 IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
7482 "Routing options are"); 7697 "Routing options are");
7483#endif 7698#endif
7484 IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING, 7699 IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
7485 QETH_CHECKSUM_DEFAULT, 7700 QETH_CHECKSUM_DEFAULT,
7486 "Checksumming options are"); 7701 "Checksumming options are");
7487 IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS, 7702 IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
7488 QETH_TR_BROADCAST_ALLRINGS, 7703 QETH_TR_BROADCAST_ALLRINGS,
7489 "Broadcast mode options are"); 7704 "Broadcast mode options are");
7490 IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL, 7705 IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
7491 QETH_TR_MACADDR_NONCANONICAL, 7706 QETH_TR_MACADDR_NONCANONICAL,
7492 "Canonical MAC addr options are"); 7707 "Canonical MAC addr options are");
7493 IGNORE_PARAM_NEQ(fake_broadcast, 0, 0, 7708 IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
7494 "Broadcast faking options are"); 7709 "Broadcast faking options are");
7495 IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN, 7710 IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
7496 DEFAULT_ADD_HHLEN,"Option add_hhlen is"); 7711 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
7497 IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is"); 7712 IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
7498 }
7499} 7713}
7500 7714
7501 7715
@@ -7525,8 +7739,7 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
7525 return -EIO; 7739 return -EIO;
7526 } 7740 }
7527 7741
7528 if (card->options.layer2) 7742 qeth_make_parameters_consistent(card);
7529 qeth_make_parameters_consistent(card);
7530 7743
7531 if ((rc = qeth_hardsetup_card(card))){ 7744 if ((rc = qeth_hardsetup_card(card))){
7532 QETH_DBF_TEXT_(setup, 2, "2err%d", rc); 7745 QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
@@ -7585,6 +7798,7 @@ qeth_set_online(struct ccwgroup_device *gdev)
7585static struct ccw_device_id qeth_ids[] = { 7798static struct ccw_device_id qeth_ids[] = {
7586 {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE}, 7799 {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
7587 {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD}, 7800 {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
7801 {CCW_DEVICE(0x1731, 0x06), driver_info:QETH_CARD_TYPE_OSN},
7588 {}, 7802 {},
7589}; 7803};
7590MODULE_DEVICE_TABLE(ccw, qeth_ids); 7804MODULE_DEVICE_TABLE(ccw, qeth_ids);
@@ -8329,6 +8543,9 @@ again:
8329 printk("qeth: removed\n"); 8543 printk("qeth: removed\n");
8330} 8544}
8331 8545
8546EXPORT_SYMBOL(qeth_osn_register);
8547EXPORT_SYMBOL(qeth_osn_deregister);
8548EXPORT_SYMBOL(qeth_osn_assist);
8332module_init(qeth_init); 8549module_init(qeth_init);
8333module_exit(qeth_exit); 8550module_exit(qeth_exit);
8334MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); 8551MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index f685ecc7da99..30e053d3cac2 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -11,7 +11,7 @@
11#include <asm/cio.h> 11#include <asm/cio.h>
12#include "qeth_mpc.h" 12#include "qeth_mpc.h"
13 13
14const char *VERSION_QETH_MPC_C = "$Revision: 1.11 $"; 14const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $";
15 15
16unsigned char IDX_ACTIVATE_READ[]={ 16unsigned char IDX_ACTIVATE_READ[]={
17 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, 17 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
@@ -138,7 +138,9 @@ unsigned char IPA_PDU_HEADER[]={
138 sizeof(struct qeth_ipa_cmd)%256, 138 sizeof(struct qeth_ipa_cmd)%256,
139 0x00, 139 0x00,
140 sizeof(struct qeth_ipa_cmd)/256, 140 sizeof(struct qeth_ipa_cmd)/256,
141 sizeof(struct qeth_ipa_cmd),0x05, 0x77,0x77,0x77,0x77, 141 sizeof(struct qeth_ipa_cmd)%256,
142 0x05,
143 0x77,0x77,0x77,0x77,
142 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 144 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
143 0x01,0x00, 145 0x01,0x00,
144 sizeof(struct qeth_ipa_cmd)/256, 146 sizeof(struct qeth_ipa_cmd)/256,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 3d916b5c5d09..7edc5f1fc0d2 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -46,13 +46,16 @@ extern unsigned char IPA_PDU_HEADER[];
46/* IP Assist related definitions */ 46/* IP Assist related definitions */
47/*****************************************************************************/ 47/*****************************************************************************/
48#define IPA_CMD_INITIATOR_HOST 0x00 48#define IPA_CMD_INITIATOR_HOST 0x00
49#define IPA_CMD_INITIATOR_HYDRA 0x01 49#define IPA_CMD_INITIATOR_OSA 0x01
50#define IPA_CMD_INITIATOR_HOST_REPLY 0x80
51#define IPA_CMD_INITIATOR_OSA_REPLY 0x81
50#define IPA_CMD_PRIM_VERSION_NO 0x01 52#define IPA_CMD_PRIM_VERSION_NO 0x01
51 53
52enum qeth_card_types { 54enum qeth_card_types {
53 QETH_CARD_TYPE_UNKNOWN = 0, 55 QETH_CARD_TYPE_UNKNOWN = 0,
54 QETH_CARD_TYPE_OSAE = 10, 56 QETH_CARD_TYPE_OSAE = 10,
55 QETH_CARD_TYPE_IQD = 1234, 57 QETH_CARD_TYPE_IQD = 1234,
58 QETH_CARD_TYPE_OSN = 11,
56}; 59};
57 60
58#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18 61#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
@@ -61,6 +64,7 @@ enum qeth_link_types {
61 QETH_LINK_TYPE_FAST_ETH = 0x01, 64 QETH_LINK_TYPE_FAST_ETH = 0x01,
62 QETH_LINK_TYPE_HSTR = 0x02, 65 QETH_LINK_TYPE_HSTR = 0x02,
63 QETH_LINK_TYPE_GBIT_ETH = 0x03, 66 QETH_LINK_TYPE_GBIT_ETH = 0x03,
67 QETH_LINK_TYPE_OSN = 0x04,
64 QETH_LINK_TYPE_10GBIT_ETH = 0x10, 68 QETH_LINK_TYPE_10GBIT_ETH = 0x10,
65 QETH_LINK_TYPE_LANE_ETH100 = 0x81, 69 QETH_LINK_TYPE_LANE_ETH100 = 0x81,
66 QETH_LINK_TYPE_LANE_TR = 0x82, 70 QETH_LINK_TYPE_LANE_TR = 0x82,
@@ -111,6 +115,9 @@ enum qeth_ipa_cmds {
111 IPA_CMD_DELGMAC = 0x24, 115 IPA_CMD_DELGMAC = 0x24,
112 IPA_CMD_SETVLAN = 0x25, 116 IPA_CMD_SETVLAN = 0x25,
113 IPA_CMD_DELVLAN = 0x26, 117 IPA_CMD_DELVLAN = 0x26,
118 IPA_CMD_SETCCID = 0x41,
119 IPA_CMD_DELCCID = 0x42,
120 IPA_CMD_MODCCID = 0x43,
114 IPA_CMD_SETIP = 0xb1, 121 IPA_CMD_SETIP = 0xb1,
115 IPA_CMD_DELIP = 0xb7, 122 IPA_CMD_DELIP = 0xb7,
116 IPA_CMD_QIPASSIST = 0xb2, 123 IPA_CMD_QIPASSIST = 0xb2,
@@ -437,8 +444,9 @@ enum qeth_ipa_arp_return_codes {
437#define QETH_ARP_DATA_SIZE 3968 444#define QETH_ARP_DATA_SIZE 3968
438#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8) 445#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
439/* Helper functions */ 446/* Helper functions */
440#define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) 447#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
441 448 (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
449
442/*****************************************************************************/ 450/*****************************************************************************/
443/* END OF IP Assist related definitions */ 451/* END OF IP Assist related definitions */
444/*****************************************************************************/ 452/*****************************************************************************/
@@ -483,6 +491,7 @@ extern unsigned char ULP_ENABLE[];
483/* Layer 2 defintions */ 491/* Layer 2 defintions */
484#define QETH_PROT_LAYER2 0x08 492#define QETH_PROT_LAYER2 0x08
485#define QETH_PROT_TCPIP 0x03 493#define QETH_PROT_TCPIP 0x03
494#define QETH_PROT_OSN2 0x0a
486#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50) 495#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
487#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19) 496#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
488 497
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index dda105b73063..f91a02db5743 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $) 3 * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to sysfs. 6 * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
20#include "qeth_mpc.h" 20#include "qeth_mpc.h"
21#include "qeth_fs.h" 21#include "qeth_fs.h"
22 22
23const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $"; 23const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $";
24 24
25/*****************************************************************************/ 25/*****************************************************************************/
26/* */ 26/* */
@@ -937,6 +937,19 @@ static struct attribute_group qeth_device_attr_group = {
937 .attrs = (struct attribute **)qeth_device_attrs, 937 .attrs = (struct attribute **)qeth_device_attrs,
938}; 938};
939 939
940static struct device_attribute * qeth_osn_device_attrs[] = {
941 &dev_attr_state,
942 &dev_attr_chpid,
943 &dev_attr_if_name,
944 &dev_attr_card_type,
945 &dev_attr_buffer_count,
946 &dev_attr_recover,
947 NULL,
948};
949
950static struct attribute_group qeth_osn_device_attr_group = {
951 .attrs = (struct attribute **)qeth_osn_device_attrs,
952};
940 953
941#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \ 954#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \
942struct device_attribute dev_attr_##_id = { \ 955struct device_attribute dev_attr_##_id = { \
@@ -1667,7 +1680,12 @@ int
1667qeth_create_device_attributes(struct device *dev) 1680qeth_create_device_attributes(struct device *dev)
1668{ 1681{
1669 int ret; 1682 int ret;
1683 struct qeth_card *card = dev->driver_data;
1670 1684
1685 if (card->info.type == QETH_CARD_TYPE_OSN)
1686 return sysfs_create_group(&dev->kobj,
1687 &qeth_osn_device_attr_group);
1688
1671 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group))) 1689 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
1672 return ret; 1690 return ret;
1673 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){ 1691 if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
@@ -1693,6 +1711,12 @@ qeth_create_device_attributes(struct device *dev)
1693void 1711void
1694qeth_remove_device_attributes(struct device *dev) 1712qeth_remove_device_attributes(struct device *dev)
1695{ 1713{
1714 struct qeth_card *card = dev->driver_data;
1715
1716 if (card->info.type == QETH_CARD_TYPE_OSN)
1717 return sysfs_remove_group(&dev->kobj,
1718 &qeth_osn_device_attr_group);
1719
1696 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); 1720 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
1697 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group); 1721 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1698 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); 1722 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);