diff options
author | Ursula Braun <braunu@de.ibm.com> | 2005-09-30 04:19:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-03 22:06:46 -0400 |
commit | 500f83abdc83d6bd472f3d103a9a9cd85df29a29 (patch) | |
tree | 33e6c948592c7c9b77ad8ebdc489e32ffb9c4b70 /drivers/s390/net/qeth_main.c | |
parent | 3c8c7b2f32c52b259daa7564fefd582146799b23 (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>
Diffstat (limited to 'drivers/s390/net/qeth_main.c')
-rw-r--r-- | drivers/s390/net/qeth_main.c | 419 |
1 files changed, 318 insertions, 101 deletions
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 | ||
1784 | static inline void | ||
1785 | qeth_prepare_control_data(struct qeth_card *card, int len, | ||
1786 | struct 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 | |||
1771 | static int | 1802 | static int |
1772 | qeth_send_control_data(struct qeth_card *card, int len, | 1803 | qeth_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 | ||
1850 | static int | 1869 | static int |
1870 | qeth_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 | |||
1897 | static inline void | ||
1898 | qeth_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 | |||
1907 | static int | ||
1908 | qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | ||
1909 | int data_len) | ||
1910 | { | ||
1911 | u16 s1, s2; | ||
1912 | |||
1913 | QETH_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 | |||
1925 | static int | ||
1851 | qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | 1926 | qeth_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 | ||
2102 | static inline struct sk_buff * | 2177 | static inline struct sk_buff * |
2103 | qeth_get_skb(unsigned int length) | 2178 | qeth_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 | ||
3157 | static int | 3246 | static int |
@@ -3466,7 +3555,7 @@ qeth_mpc_initialize(struct qeth_card *card) | |||
3466 | 3555 | ||
3467 | return 0; | 3556 | return 0; |
3468 | out_qdio: | 3557 | out_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 | |||
3782 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, | 3878 | qeth_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 | ||
5486 | int | ||
5487 | qeth_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 | |||
5510 | static struct net_device * | ||
5511 | qeth_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 | |||
5536 | int | ||
5537 | qeth_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 | |||
5558 | void | ||
5559 | qeth_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 | |||
5373 | static void | 5574 | static void |
5374 | qeth_delete_mc_addresses(struct qeth_card *card) | 5575 | qeth_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) | |||
7469 | static void qeth_make_parameters_consistent(struct qeth_card *card) | 7680 | static 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) | |||
7585 | static struct ccw_device_id qeth_ids[] = { | 7798 | static 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 | }; |
7590 | MODULE_DEVICE_TABLE(ccw, qeth_ids); | 7804 | MODULE_DEVICE_TABLE(ccw, qeth_ids); |
@@ -8329,6 +8543,9 @@ again: | |||
8329 | printk("qeth: removed\n"); | 8543 | printk("qeth: removed\n"); |
8330 | } | 8544 | } |
8331 | 8545 | ||
8546 | EXPORT_SYMBOL(qeth_osn_register); | ||
8547 | EXPORT_SYMBOL(qeth_osn_deregister); | ||
8548 | EXPORT_SYMBOL(qeth_osn_assist); | ||
8332 | module_init(qeth_init); | 8549 | module_init(qeth_init); |
8333 | module_exit(qeth_exit); | 8550 | module_exit(qeth_exit); |
8334 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 8551 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); |