diff options
author | Greg KH <greg@press.(none)> | 2005-10-28 13:13:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 13:13:16 -0400 |
commit | 6fbfddcb52d8d9fa2cd209f5ac2a1c87497d55b5 (patch) | |
tree | c0414e89678fcef7ce3493e048d855bde781ae8d /drivers/s390/net/qeth_main.c | |
parent | 1a222bca26ca691e83be1b08f5e96ae96d0d8cae (diff) | |
parent | 27d1097d39509494706eaa2620ef3b1e780a3224 (diff) |
Merge ../bleed-2.6
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>"); |