aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-26 13:27:39 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-26 13:27:39 -0400
commitf49809fe9b39e22b0f6f75c86295ce216ce3e374 (patch)
tree05f8c05ee71307c9ab02663cfaa5f08a21c6629f
parentcdbbde14cb55dd10771ce79154f787322d88411b (diff)
parentc1ef1f351db70ad60c793b8218dd9f6739cfd66d (diff)
Automatic merge of 'for-linus' branch from
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/forcedeth.c103
-rw-r--r--drivers/net/iseries_veth.c32
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/ns83820.c69
-rw-r--r--drivers/net/sis900.c52
-rw-r--r--drivers/net/tlan.c12
-rw-r--r--drivers/net/wireless/airo.c150
-rw-r--r--drivers/net/wireless/atmel_cs.c1
-rw-r--r--drivers/s390/net/Makefile3
-rw-r--r--drivers/s390/net/ctcdbug.h12
-rw-r--r--drivers/s390/net/ctcmain.c616
-rw-r--r--drivers/s390/net/ctcmain.h276
-rw-r--r--drivers/s390/net/ctctty.c5
-rw-r--r--drivers/s390/net/cu3088.c4
-rw-r--r--drivers/s390/net/cu3088.h3
-rw-r--r--drivers/s390/net/iucv.c10
-rw-r--r--drivers/s390/net/lcs.c33
-rw-r--r--drivers/s390/net/qeth.h35
-rw-r--r--drivers/s390/net/qeth_eddp.c51
-rw-r--r--drivers/s390/net/qeth_main.c316
-rw-r--r--drivers/s390/net/qeth_tso.c285
-rw-r--r--drivers/s390/net/qeth_tso.h166
23 files changed, 1222 insertions, 1019 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3a0a55b62aaf..7c5c1acd1474 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1555,6 +1555,7 @@ config SIS900
1555 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" 1555 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
1556 depends on NET_PCI && PCI 1556 depends on NET_PCI && PCI
1557 select CRC32 1557 select CRC32
1558 select MII
1558 ---help--- 1559 ---help---
1559 This is a driver for the Fast Ethernet PCI network cards based on 1560 This is a driver for the Fast Ethernet PCI network cards based on
1560 the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in 1561 the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index cda48c5d72a9..4ebcd052e150 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -81,6 +81,7 @@
81 * cause DMA to kfree'd memory. 81 * cause DMA to kfree'd memory.
82 * 0.31: 14 Nov 2004: ethtool support for getting/setting link 82 * 0.31: 14 Nov 2004: ethtool support for getting/setting link
83 * capabilities. 83 * capabilities.
84 * 0.32: 16 Apr 2005: RX_ERROR4 handling added.
84 * 85 *
85 * Known bugs: 86 * Known bugs:
86 * We suspect that on some hardware no TX done interrupts are generated. 87 * We suspect that on some hardware no TX done interrupts are generated.
@@ -92,7 +93,7 @@
92 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 93 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
93 * superfluous timer interrupts from the nic. 94 * superfluous timer interrupts from the nic.
94 */ 95 */
95#define FORCEDETH_VERSION "0.31" 96#define FORCEDETH_VERSION "0.32"
96#define DRV_NAME "forcedeth" 97#define DRV_NAME "forcedeth"
97 98
98#include <linux/module.h> 99#include <linux/module.h>
@@ -109,6 +110,7 @@
109#include <linux/mii.h> 110#include <linux/mii.h>
110#include <linux/random.h> 111#include <linux/random.h>
111#include <linux/init.h> 112#include <linux/init.h>
113#include <linux/if_vlan.h>
112 114
113#include <asm/irq.h> 115#include <asm/irq.h>
114#include <asm/io.h> 116#include <asm/io.h>
@@ -1013,6 +1015,59 @@ static void nv_tx_timeout(struct net_device *dev)
1013 spin_unlock_irq(&np->lock); 1015 spin_unlock_irq(&np->lock);
1014} 1016}
1015 1017
1018/*
1019 * Called when the nic notices a mismatch between the actual data len on the
1020 * wire and the len indicated in the 802 header
1021 */
1022static int nv_getlen(struct net_device *dev, void *packet, int datalen)
1023{
1024 int hdrlen; /* length of the 802 header */
1025 int protolen; /* length as stored in the proto field */
1026
1027 /* 1) calculate len according to header */
1028 if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) {
1029 protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto );
1030 hdrlen = VLAN_HLEN;
1031 } else {
1032 protolen = ntohs( ((struct ethhdr *)packet)->h_proto);
1033 hdrlen = ETH_HLEN;
1034 }
1035 dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n",
1036 dev->name, datalen, protolen, hdrlen);
1037 if (protolen > ETH_DATA_LEN)
1038 return datalen; /* Value in proto field not a len, no checks possible */
1039
1040 protolen += hdrlen;
1041 /* consistency checks: */
1042 if (datalen > ETH_ZLEN) {
1043 if (datalen >= protolen) {
1044 /* more data on wire than in 802 header, trim of
1045 * additional data.
1046 */
1047 dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
1048 dev->name, protolen);
1049 return protolen;
1050 } else {
1051 /* less data on wire than mentioned in header.
1052 * Discard the packet.
1053 */
1054 dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n",
1055 dev->name);
1056 return -1;
1057 }
1058 } else {
1059 /* short packet. Accept only if 802 values are also short */
1060 if (protolen > ETH_ZLEN) {
1061 dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n",
1062 dev->name);
1063 return -1;
1064 }
1065 dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n",
1066 dev->name, datalen);
1067 return datalen;
1068 }
1069}
1070
1016static void nv_rx_process(struct net_device *dev) 1071static void nv_rx_process(struct net_device *dev)
1017{ 1072{
1018 struct fe_priv *np = get_nvpriv(dev); 1073 struct fe_priv *np = get_nvpriv(dev);
@@ -1064,7 +1119,7 @@ static void nv_rx_process(struct net_device *dev)
1064 np->stats.rx_errors++; 1119 np->stats.rx_errors++;
1065 goto next_pkt; 1120 goto next_pkt;
1066 } 1121 }
1067 if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { 1122 if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
1068 np->stats.rx_errors++; 1123 np->stats.rx_errors++;
1069 goto next_pkt; 1124 goto next_pkt;
1070 } 1125 }
@@ -1078,22 +1133,24 @@ static void nv_rx_process(struct net_device *dev)
1078 np->stats.rx_errors++; 1133 np->stats.rx_errors++;
1079 goto next_pkt; 1134 goto next_pkt;
1080 } 1135 }
1081 if (Flags & NV_RX_ERROR) { 1136 if (Flags & NV_RX_ERROR4) {
1082 /* framing errors are soft errors, the rest is fatal. */ 1137 len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
1083 if (Flags & NV_RX_FRAMINGERR) { 1138 if (len < 0) {
1084 if (Flags & NV_RX_SUBSTRACT1) {
1085 len--;
1086 }
1087 } else {
1088 np->stats.rx_errors++; 1139 np->stats.rx_errors++;
1089 goto next_pkt; 1140 goto next_pkt;
1090 } 1141 }
1091 } 1142 }
1143 /* framing errors are soft errors. */
1144 if (Flags & NV_RX_FRAMINGERR) {
1145 if (Flags & NV_RX_SUBSTRACT1) {
1146 len--;
1147 }
1148 }
1092 } else { 1149 } else {
1093 if (!(Flags & NV_RX2_DESCRIPTORVALID)) 1150 if (!(Flags & NV_RX2_DESCRIPTORVALID))
1094 goto next_pkt; 1151 goto next_pkt;
1095 1152
1096 if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) { 1153 if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
1097 np->stats.rx_errors++; 1154 np->stats.rx_errors++;
1098 goto next_pkt; 1155 goto next_pkt;
1099 } 1156 }
@@ -1107,17 +1164,19 @@ static void nv_rx_process(struct net_device *dev)
1107 np->stats.rx_errors++; 1164 np->stats.rx_errors++;
1108 goto next_pkt; 1165 goto next_pkt;
1109 } 1166 }
1110 if (Flags & NV_RX2_ERROR) { 1167 if (Flags & NV_RX2_ERROR4) {
1111 /* framing errors are soft errors, the rest is fatal. */ 1168 len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
1112 if (Flags & NV_RX2_FRAMINGERR) { 1169 if (len < 0) {
1113 if (Flags & NV_RX2_SUBSTRACT1) {
1114 len--;
1115 }
1116 } else {
1117 np->stats.rx_errors++; 1170 np->stats.rx_errors++;
1118 goto next_pkt; 1171 goto next_pkt;
1119 } 1172 }
1120 } 1173 }
1174 /* framing errors are soft errors */
1175 if (Flags & NV_RX2_FRAMINGERR) {
1176 if (Flags & NV_RX2_SUBSTRACT1) {
1177 len--;
1178 }
1179 }
1121 Flags &= NV_RX2_CHECKSUMMASK; 1180 Flags &= NV_RX2_CHECKSUMMASK;
1122 if (Flags == NV_RX2_CHECKSUMOK1 || 1181 if (Flags == NV_RX2_CHECKSUMOK1 ||
1123 Flags == NV_RX2_CHECKSUMOK2 || 1182 Flags == NV_RX2_CHECKSUMOK2 ||
@@ -1480,6 +1539,13 @@ static void nv_do_nic_poll(unsigned long data)
1480 enable_irq(dev->irq); 1539 enable_irq(dev->irq);
1481} 1540}
1482 1541
1542#ifdef CONFIG_NET_POLL_CONTROLLER
1543static void nv_poll_controller(struct net_device *dev)
1544{
1545 nv_do_nic_poll((unsigned long) dev);
1546}
1547#endif
1548
1483static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1549static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1484{ 1550{
1485 struct fe_priv *np = get_nvpriv(dev); 1551 struct fe_priv *np = get_nvpriv(dev);
@@ -1962,6 +2028,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
1962 dev->get_stats = nv_get_stats; 2028 dev->get_stats = nv_get_stats;
1963 dev->change_mtu = nv_change_mtu; 2029 dev->change_mtu = nv_change_mtu;
1964 dev->set_multicast_list = nv_set_multicast; 2030 dev->set_multicast_list = nv_set_multicast;
2031#ifdef CONFIG_NET_POLL_CONTROLLER
2032 dev->poll_controller = nv_poll_controller;
2033#endif
1965 SET_ETHTOOL_OPS(dev, &ops); 2034 SET_ETHTOOL_OPS(dev, &ops);
1966 dev->tx_timeout = nv_tx_timeout; 2035 dev->tx_timeout = nv_tx_timeout;
1967 dev->watchdog_timeo = NV_WATCHDOG_TIMEO; 2036 dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 855f8b2cf13b..13ed8dc1e91d 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -924,7 +924,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
924 924
925 spin_lock_irqsave(&cnx->lock, flags); 925 spin_lock_irqsave(&cnx->lock, flags);
926 926
927 if (! cnx->state & VETH_STATE_READY) 927 if (! (cnx->state & VETH_STATE_READY))
928 goto drop; 928 goto drop;
929 929
930 if ((skb->len - 14) > VETH_MAX_MTU) 930 if ((skb->len - 14) > VETH_MAX_MTU)
@@ -1023,6 +1023,8 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
1023 1023
1024 lpmask = veth_transmit_to_many(skb, lpmask, dev); 1024 lpmask = veth_transmit_to_many(skb, lpmask, dev);
1025 1025
1026 dev->trans_start = jiffies;
1027
1026 if (! lpmask) { 1028 if (! lpmask) {
1027 dev_kfree_skb(skb); 1029 dev_kfree_skb(skb);
1028 } else { 1030 } else {
@@ -1262,13 +1264,18 @@ static void veth_receive(struct veth_lpar_connection *cnx,
1262 1264
1263 vlan = skb->data[9]; 1265 vlan = skb->data[9];
1264 dev = veth_dev[vlan]; 1266 dev = veth_dev[vlan];
1265 if (! dev) 1267 if (! dev) {
1266 /* Some earlier versions of the driver sent 1268 /*
1267 broadcasts down all connections, even to 1269 * Some earlier versions of the driver sent
1268 lpars that weren't on the relevant vlan. 1270 * broadcasts down all connections, even to lpars
1269 So ignore packets belonging to a vlan we're 1271 * that weren't on the relevant vlan. So ignore
1270 not on. */ 1272 * packets belonging to a vlan we're not on.
1273 * We can also be here if we receive packets while
1274 * the driver is going down, because then dev is NULL.
1275 */
1276 dev_kfree_skb_irq(skb);
1271 continue; 1277 continue;
1278 }
1272 1279
1273 port = (struct veth_port *)dev->priv; 1280 port = (struct veth_port *)dev->priv;
1274 dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000; 1281 dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000;
@@ -1381,18 +1388,25 @@ void __exit veth_module_cleanup(void)
1381{ 1388{
1382 int i; 1389 int i;
1383 1390
1384 vio_unregister_driver(&veth_driver); 1391 /* Stop the queues first to stop any new packets being sent. */
1392 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++)
1393 if (veth_dev[i])
1394 netif_stop_queue(veth_dev[i]);
1385 1395
1396 /* Stop the connections before we unregister the driver. This
1397 * ensures there's no skbs lying around holding the device open. */
1386 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) 1398 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
1387 veth_stop_connection(i); 1399 veth_stop_connection(i);
1388 1400
1389 HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); 1401 HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
1390 1402
1391 /* Hypervisor callbacks may have scheduled more work while we 1403 /* Hypervisor callbacks may have scheduled more work while we
1392 * were destroying connections. Now that we've disconnected from 1404 * were stoping connections. Now that we've disconnected from
1393 * the hypervisor make sure everything's finished. */ 1405 * the hypervisor make sure everything's finished. */
1394 flush_scheduled_work(); 1406 flush_scheduled_work();
1395 1407
1408 vio_unregister_driver(&veth_driver);
1409
1396 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) 1410 for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
1397 veth_destroy_connection(i); 1411 veth_destroy_connection(i);
1398 1412
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 223bdadd4c0d..babb59e146ea 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2433,9 +2433,9 @@ static void __set_rx_mode(struct net_device *dev)
2433 rx_mode = RxFilterEnable | AcceptBroadcast 2433 rx_mode = RxFilterEnable | AcceptBroadcast
2434 | AcceptMulticast | AcceptMyPhys; 2434 | AcceptMulticast | AcceptMyPhys;
2435 for (i = 0; i < 64; i += 2) { 2435 for (i = 0; i < 64; i += 2) {
2436 writew(HASH_TABLE + i, ioaddr + RxFilterAddr); 2436 writel(HASH_TABLE + i, ioaddr + RxFilterAddr);
2437 writew((mc_filter[i+1]<<8) + mc_filter[i], 2437 writel((mc_filter[i + 1] << 8) + mc_filter[i],
2438 ioaddr + RxFilterData); 2438 ioaddr + RxFilterData);
2439 } 2439 }
2440 } 2440 }
2441 writel(rx_mode, ioaddr + RxFilterAddr); 2441 writel(rx_mode, ioaddr + RxFilterAddr);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 2fcc181a8624..c336b46bd332 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1,4 +1,4 @@
1#define _VERSION "0.20" 1#define VERSION "0.22"
2/* ns83820.c by Benjamin LaHaise with contributions. 2/* ns83820.c by Benjamin LaHaise with contributions.
3 * 3 *
4 * Questions/comments/discussion to linux-ns83820@kvack.org. 4 * Questions/comments/discussion to linux-ns83820@kvack.org.
@@ -63,9 +63,11 @@
63 * - fix missed txok introduced during performance 63 * - fix missed txok introduced during performance
64 * tuning 64 * tuning
65 * 0.20 - fix stupid RFEN thinko. i am such a smurf. 65 * 0.20 - fix stupid RFEN thinko. i am such a smurf.
66 *
67 * 20040828 0.21 - add hardware vlan accleration 66 * 20040828 0.21 - add hardware vlan accleration
68 * by Neil Horman <nhorman@redhat.com> 67 * by Neil Horman <nhorman@redhat.com>
68 * 20050406 0.22 - improved DAC ifdefs from Andi Kleen
69 * - removal of dead code from Adrian Bunk
70 * - fix half duplex collision behaviour
69 * Driver Overview 71 * Driver Overview
70 * =============== 72 * ===============
71 * 73 *
@@ -129,18 +131,6 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */
129#undef Dprintk 131#undef Dprintk
130#define Dprintk dprintk 132#define Dprintk dprintk
131 133
132#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
133#define USE_64BIT_ADDR "+"
134#endif
135
136#if defined(USE_64BIT_ADDR)
137#define VERSION _VERSION USE_64BIT_ADDR
138#define TRY_DAC 1
139#else
140#define VERSION _VERSION
141#define TRY_DAC 0
142#endif
143
144/* tunables */ 134/* tunables */
145#define RX_BUF_SIZE 1500 /* 8192 */ 135#define RX_BUF_SIZE 1500 /* 8192 */
146#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 136#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -386,22 +376,16 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */
386#define LINK_DOWN 0x02 376#define LINK_DOWN 0x02
387#define LINK_UP 0x04 377#define LINK_UP 0x04
388 378
389#ifdef USE_64BIT_ADDR 379#define HW_ADDR_LEN sizeof(dma_addr_t)
390#define HW_ADDR_LEN 8
391#define desc_addr_set(desc, addr) \ 380#define desc_addr_set(desc, addr) \
392 do { \ 381 do { \
393 u64 __addr = (addr); \ 382 ((desc)[0] = cpu_to_le32(addr)); \
394 (desc)[0] = cpu_to_le32(__addr); \ 383 if (HW_ADDR_LEN == 8) \
395 (desc)[1] = cpu_to_le32(__addr >> 32); \ 384 (desc)[1] = cpu_to_le32(((u64)addr) >> 32); \
396 } while(0) 385 } while(0)
397#define desc_addr_get(desc) \ 386#define desc_addr_get(desc) \
398 (((u64)le32_to_cpu((desc)[1]) << 32) \ 387 (le32_to_cpu((desc)[0]) | \
399 | le32_to_cpu((desc)[0])) 388 (HW_ADDR_LEN == 8 ? ((dma_addr_t)le32_to_cpu((desc)[1]))<<32 : 0))
400#else
401#define HW_ADDR_LEN 4
402#define desc_addr_set(desc, addr) ((desc)[0] = cpu_to_le32(addr))
403#define desc_addr_get(desc) (le32_to_cpu((desc)[0]))
404#endif
405 389
406#define DESC_LINK 0 390#define DESC_LINK 0
407#define DESC_BUFPTR (DESC_LINK + HW_ADDR_LEN/4) 391#define DESC_BUFPTR (DESC_LINK + HW_ADDR_LEN/4)
@@ -727,11 +711,23 @@ static void fastcall phy_intr(struct net_device *ndev)
727 speed = ((cfg / CFG_SPDSTS0) & 3); 711 speed = ((cfg / CFG_SPDSTS0) & 3);
728 fullduplex = (cfg & CFG_DUPSTS); 712 fullduplex = (cfg & CFG_DUPSTS);
729 713
730 if (fullduplex) 714 if (fullduplex) {
731 new_cfg |= CFG_SB; 715 new_cfg |= CFG_SB;
716 writel(readl(dev->base + TXCFG)
717 | TXCFG_CSI | TXCFG_HBI,
718 dev->base + TXCFG);
719 writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
720 dev->base + RXCFG);
721 } else {
722 writel(readl(dev->base + TXCFG)
723 & ~(TXCFG_CSI | TXCFG_HBI),
724 dev->base + TXCFG);
725 writel(readl(dev->base + RXCFG) & ~(RXCFG_RX_FD),
726 dev->base + RXCFG);
727 }
732 728
733 if ((cfg & CFG_LNKSTS) && 729 if ((cfg & CFG_LNKSTS) &&
734 ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) { 730 ((new_cfg ^ dev->CFG_cache) != 0)) {
735 writel(new_cfg, dev->base + CFG); 731 writel(new_cfg, dev->base + CFG);
736 dev->CFG_cache = new_cfg; 732 dev->CFG_cache = new_cfg;
737 } 733 }
@@ -1189,7 +1185,6 @@ again:
1189 1185
1190 for (;;) { 1186 for (;;) {
1191 volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE); 1187 volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
1192 u32 residue = 0;
1193 1188
1194 dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len, 1189 dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
1195 (unsigned long long)buf); 1190 (unsigned long long)buf);
@@ -1199,17 +1194,11 @@ again:
1199 desc_addr_set(desc + DESC_BUFPTR, buf); 1194 desc_addr_set(desc + DESC_BUFPTR, buf);
1200 desc[DESC_EXTSTS] = cpu_to_le32(extsts); 1195 desc[DESC_EXTSTS] = cpu_to_le32(extsts);
1201 1196
1202 cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0); 1197 cmdsts = ((nr_frags) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
1203 cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN; 1198 cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN;
1204 cmdsts |= len; 1199 cmdsts |= len;
1205 desc[DESC_CMDSTS] = cpu_to_le32(cmdsts); 1200 desc[DESC_CMDSTS] = cpu_to_le32(cmdsts);
1206 1201
1207 if (residue) {
1208 buf += len;
1209 len = residue;
1210 continue;
1211 }
1212
1213 if (!nr_frags) 1202 if (!nr_frags)
1214 break; 1203 break;
1215 1204
@@ -1841,7 +1830,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1841 int using_dac = 0; 1830 int using_dac = 0;
1842 1831
1843 /* See if we can set the dma mask early on; failure is fatal. */ 1832 /* See if we can set the dma mask early on; failure is fatal. */
1844 if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) { 1833 if (sizeof(dma_addr_t) == 8 &&
1834 !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) {
1845 using_dac = 1; 1835 using_dac = 1;
1846 } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) { 1836 } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
1847 using_dac = 0; 1837 using_dac = 0;
@@ -1972,9 +1962,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1972 /* When compiled with 64 bit addressing, we must always enable 1962 /* When compiled with 64 bit addressing, we must always enable
1973 * the 64 bit descriptor format. 1963 * the 64 bit descriptor format.
1974 */ 1964 */
1975#ifdef USE_64BIT_ADDR 1965 if (sizeof(dma_addr_t) == 8)
1976 dev->CFG_cache |= CFG_M64ADDR; 1966 dev->CFG_cache |= CFG_M64ADDR;
1977#endif
1978 if (using_dac) 1967 if (using_dac)
1979 dev->CFG_cache |= CFG_T64ADDR; 1968 dev->CFG_cache |= CFG_T64ADDR;
1980 1969
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 3e9d9aab0588..3107aed0fb51 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -162,6 +162,7 @@ struct sis900_private {
162 struct mii_phy * mii; 162 struct mii_phy * mii;
163 struct mii_phy * first_mii; /* record the first mii structure */ 163 struct mii_phy * first_mii; /* record the first mii structure */
164 unsigned int cur_phy; 164 unsigned int cur_phy;
165 struct mii_if_info mii_info;
165 166
166 struct timer_list timer; /* Link status detection timer. */ 167 struct timer_list timer; /* Link status detection timer. */
167 u8 autong_complete; /* 1: auto-negotiate complete */ 168 u8 autong_complete; /* 1: auto-negotiate complete */
@@ -203,7 +204,7 @@ static int sis900_open(struct net_device *net_dev);
203static int sis900_mii_probe (struct net_device * net_dev); 204static int sis900_mii_probe (struct net_device * net_dev);
204static void sis900_init_rxfilter (struct net_device * net_dev); 205static void sis900_init_rxfilter (struct net_device * net_dev);
205static u16 read_eeprom(long ioaddr, int location); 206static u16 read_eeprom(long ioaddr, int location);
206static u16 mdio_read(struct net_device *net_dev, int phy_id, int location); 207static int mdio_read(struct net_device *net_dev, int phy_id, int location);
207static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val); 208static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val);
208static void sis900_timer(unsigned long data); 209static void sis900_timer(unsigned long data);
209static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy); 210static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy);
@@ -478,7 +479,13 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
478 sis_priv->msg_enable = sis900_debug; 479 sis_priv->msg_enable = sis900_debug;
479 else 480 else
480 sis_priv->msg_enable = SIS900_DEF_MSG; 481 sis_priv->msg_enable = SIS900_DEF_MSG;
481 482
483 sis_priv->mii_info.dev = net_dev;
484 sis_priv->mii_info.mdio_read = mdio_read;
485 sis_priv->mii_info.mdio_write = mdio_write;
486 sis_priv->mii_info.phy_id_mask = 0x1f;
487 sis_priv->mii_info.reg_num_mask = 0x1f;
488
482 /* Get Mac address according to the chip revision */ 489 /* Get Mac address according to the chip revision */
483 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev)); 490 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev));
484 if(netif_msg_probe(sis_priv)) 491 if(netif_msg_probe(sis_priv))
@@ -725,6 +732,8 @@ static u16 sis900_default_phy(struct net_device * net_dev)
725 pci_name(sis_priv->pci_dev), sis_priv->cur_phy); 732 pci_name(sis_priv->pci_dev), sis_priv->cur_phy);
726 } 733 }
727 734
735 sis_priv->mii_info.phy_id = sis_priv->cur_phy;
736
728 status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL); 737 status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
729 status &= (~MII_CNTL_ISOLATE); 738 status &= (~MII_CNTL_ISOLATE);
730 739
@@ -852,7 +861,7 @@ static void mdio_reset(long mdio_addr)
852 * Please see SiS7014 or ICS spec 861 * Please see SiS7014 or ICS spec
853 */ 862 */
854 863
855static u16 mdio_read(struct net_device *net_dev, int phy_id, int location) 864static int mdio_read(struct net_device *net_dev, int phy_id, int location)
856{ 865{
857 long mdio_addr = net_dev->base_addr + mear; 866 long mdio_addr = net_dev->base_addr + mear;
858 int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift); 867 int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
@@ -1966,10 +1975,47 @@ static void sis900_set_msglevel(struct net_device *net_dev, u32 value)
1966 sis_priv->msg_enable = value; 1975 sis_priv->msg_enable = value;
1967} 1976}
1968 1977
1978static u32 sis900_get_link(struct net_device *net_dev)
1979{
1980 struct sis900_private *sis_priv = net_dev->priv;
1981 return mii_link_ok(&sis_priv->mii_info);
1982}
1983
1984static int sis900_get_settings(struct net_device *net_dev,
1985 struct ethtool_cmd *cmd)
1986{
1987 struct sis900_private *sis_priv = net_dev->priv;
1988 spin_lock_irq(&sis_priv->lock);
1989 mii_ethtool_gset(&sis_priv->mii_info, cmd);
1990 spin_unlock_irq(&sis_priv->lock);
1991 return 0;
1992}
1993
1994static int sis900_set_settings(struct net_device *net_dev,
1995 struct ethtool_cmd *cmd)
1996{
1997 struct sis900_private *sis_priv = net_dev->priv;
1998 int rt;
1999 spin_lock_irq(&sis_priv->lock);
2000 rt = mii_ethtool_sset(&sis_priv->mii_info, cmd);
2001 spin_unlock_irq(&sis_priv->lock);
2002 return rt;
2003}
2004
2005static int sis900_nway_reset(struct net_device *net_dev)
2006{
2007 struct sis900_private *sis_priv = net_dev->priv;
2008 return mii_nway_restart(&sis_priv->mii_info);
2009}
2010
1969static struct ethtool_ops sis900_ethtool_ops = { 2011static struct ethtool_ops sis900_ethtool_ops = {
1970 .get_drvinfo = sis900_get_drvinfo, 2012 .get_drvinfo = sis900_get_drvinfo,
1971 .get_msglevel = sis900_get_msglevel, 2013 .get_msglevel = sis900_get_msglevel,
1972 .set_msglevel = sis900_set_msglevel, 2014 .set_msglevel = sis900_set_msglevel,
2015 .get_link = sis900_get_link,
2016 .get_settings = sis900_get_settings,
2017 .set_settings = sis900_set_settings,
2018 .nway_reset = sis900_nway_reset,
1973}; 2019};
1974 2020
1975/** 2021/**
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index a7ffa64502dd..9680a308c62b 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -193,6 +193,12 @@ static int aui[MAX_TLAN_BOARDS];
193static int duplex[MAX_TLAN_BOARDS]; 193static int duplex[MAX_TLAN_BOARDS];
194static int speed[MAX_TLAN_BOARDS]; 194static int speed[MAX_TLAN_BOARDS];
195static int boards_found; 195static int boards_found;
196module_param_array(aui, int, NULL, 0);
197module_param_array(duplex, int, NULL, 0);
198module_param_array(speed, int, NULL, 0);
199MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
200MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
201MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
196 202
197MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>"); 203MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
198MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); 204MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
@@ -204,8 +210,13 @@ MODULE_LICENSE("GPL");
204 210
205/* Turn on debugging. See Documentation/networking/tlan.txt for details */ 211/* Turn on debugging. See Documentation/networking/tlan.txt for details */
206static int debug; 212static int debug;
213module_param(debug, int, 0);
214MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
207 215
208static int bbuf; 216static int bbuf;
217module_param(bbuf, int, 0);
218MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
219
209static u8 *TLanPadBuffer; 220static u8 *TLanPadBuffer;
210static dma_addr_t TLanPadBufferDMA; 221static dma_addr_t TLanPadBufferDMA;
211static char TLanSignature[] = "TLAN"; 222static char TLanSignature[] = "TLAN";
@@ -2381,6 +2392,7 @@ TLan_FinishReset( struct net_device *dev )
2381 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); 2392 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
2382 return; 2393 return;
2383 } 2394 }
2395 TLan_SetMulticastList(dev);
2384 2396
2385} /* TLan_FinishReset */ 2397} /* TLan_FinishReset */
2386 2398
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 463c789cdc77..fb10a2db63ad 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -754,7 +754,7 @@ typedef struct {
754 u8 zero; 754 u8 zero;
755 u8 ssidLen; 755 u8 ssidLen;
756 u8 ssid[32]; 756 u8 ssid[32];
757 u16 rssi; 757 u16 dBm;
758#define CAP_ESS (1<<0) 758#define CAP_ESS (1<<0)
759#define CAP_IBSS (1<<1) 759#define CAP_IBSS (1<<1)
760#define CAP_PRIVACY (1<<4) 760#define CAP_PRIVACY (1<<4)
@@ -1125,6 +1125,9 @@ static int micsetup(struct airo_info *ai);
1125static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); 1125static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1126static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); 1126static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1127 1127
1128static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
1129static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
1130
1128#include <linux/crypto.h> 1131#include <linux/crypto.h>
1129#endif 1132#endif
1130 1133
@@ -1713,6 +1716,7 @@ static int readBSSListRid(struct airo_info *ai, int first,
1713 list->fh.dwell = le16_to_cpu(list->fh.dwell); 1716 list->fh.dwell = le16_to_cpu(list->fh.dwell);
1714 list->dsChannel = le16_to_cpu(list->dsChannel); 1717 list->dsChannel = le16_to_cpu(list->dsChannel);
1715 list->atimWindow = le16_to_cpu(list->atimWindow); 1718 list->atimWindow = le16_to_cpu(list->atimWindow);
1719 list->dBm = le16_to_cpu(list->dBm);
1716 return rc; 1720 return rc;
1717} 1721}
1718 1722
@@ -3245,7 +3249,10 @@ badrx:
3245 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; 3249 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3246 else 3250 else
3247 wstats.level = (hdr.rssi[1] + 321) / 2; 3251 wstats.level = (hdr.rssi[1] + 321) / 2;
3248 wstats.updated = 3; 3252 wstats.noise = apriv->wstats.qual.noise;
3253 wstats.updated = IW_QUAL_LEVEL_UPDATED
3254 | IW_QUAL_QUAL_UPDATED
3255 | IW_QUAL_NOISE_UPDATED;
3249 /* Update spy records */ 3256 /* Update spy records */
3250 wireless_spy_update(dev, sa, &wstats); 3257 wireless_spy_update(dev, sa, &wstats);
3251 } 3258 }
@@ -3588,7 +3595,10 @@ void mpi_receive_802_11 (struct airo_info *ai)
3588 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm; 3595 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3589 else 3596 else
3590 wstats.level = (hdr.rssi[1] + 321) / 2; 3597 wstats.level = (hdr.rssi[1] + 321) / 2;
3591 wstats.updated = 3; 3598 wstats.noise = ai->wstats.qual.noise;
3599 wstats.updated = IW_QUAL_QUAL_UPDATED
3600 | IW_QUAL_LEVEL_UPDATED
3601 | IW_QUAL_NOISE_UPDATED;
3592 /* Update spy records */ 3602 /* Update spy records */
3593 wireless_spy_update(ai->dev, sa, &wstats); 3603 wireless_spy_update(ai->dev, sa, &wstats);
3594 } 3604 }
@@ -3679,7 +3689,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3679 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock); 3689 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3680 if ( status == SUCCESS ) { 3690 if ( status == SUCCESS ) {
3681 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL) 3691 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3682 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); 3692 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3683 } 3693 }
3684 else { 3694 else {
3685 if (ai->rssi) { 3695 if (ai->rssi) {
@@ -5348,7 +5358,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5348 (int)BSSList_rid.bssid[5], 5358 (int)BSSList_rid.bssid[5],
5349 (int)BSSList_rid.ssidLen, 5359 (int)BSSList_rid.ssidLen,
5350 BSSList_rid.ssid, 5360 BSSList_rid.ssid,
5351 (int)BSSList_rid.rssi); 5361 (int)BSSList_rid.dBm);
5352 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n", 5362 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5353 (int)BSSList_rid.dsChannel, 5363 (int)BSSList_rid.dsChannel,
5354 BSSList_rid.cap & CAP_ESS ? "ESS" : "", 5364 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
@@ -5593,6 +5603,29 @@ static void __exit airo_cleanup_module( void )
5593 * would not work at all... - Jean II 5603 * would not work at all... - Jean II
5594 */ 5604 */
5595 5605
5606static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5607{
5608 if( !rssi_rid )
5609 return 0;
5610
5611 return (0x100 - rssi_rid[rssi].rssidBm);
5612}
5613
5614static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5615{
5616 int i;
5617
5618 if( !rssi_rid )
5619 return 0;
5620
5621 for( i = 0; i < 256; i++ )
5622 if (rssi_rid[i].rssidBm == dbm)
5623 return rssi_rid[i].rssipct;
5624
5625 return 0;
5626}
5627
5628
5596static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid) 5629static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5597{ 5630{
5598 int quality = 0; 5631 int quality = 0;
@@ -6443,11 +6476,29 @@ static int airo_get_range(struct net_device *dev,
6443 } 6476 }
6444 range->num_frequency = k; 6477 range->num_frequency = k;
6445 6478
6479 range->sensitivity = 65535;
6480
6446 /* Hum... Should put the right values there */ 6481 /* Hum... Should put the right values there */
6447 range->max_qual.qual = airo_get_max_quality(&cap_rid); 6482 if (local->rssi)
6448 range->max_qual.level = 0x100 - 120; /* -120 dBm */ 6483 range->max_qual.qual = 100; /* % */
6484 else
6485 range->max_qual.qual = airo_get_max_quality(&cap_rid);
6486 range->max_qual.level = 0; /* 0 means we use dBm */
6449 range->max_qual.noise = 0; 6487 range->max_qual.noise = 0;
6450 range->sensitivity = 65535; 6488 range->max_qual.updated = 0;
6489
6490 /* Experimental measurements - boundary 11/5.5 Mb/s */
6491 /* Note : with or without the (local->rssi), results
6492 * are somewhat different. - Jean II */
6493 if (local->rssi) {
6494 range->avg_qual.qual = 50; /* % */
6495 range->avg_qual.level = 186; /* -70 dBm */
6496 } else {
6497 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6498 range->avg_qual.level = 176; /* -80 dBm */
6499 }
6500 range->avg_qual.noise = 0;
6501 range->avg_qual.updated = 0;
6451 6502
6452 for(i = 0 ; i < 8 ; i++) { 6503 for(i = 0 ; i < 8 ; i++) {
6453 range->bitrate[i] = cap_rid.supportedRates[i] * 500000; 6504 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
@@ -6508,15 +6559,6 @@ static int airo_get_range(struct net_device *dev,
6508 range->max_retry = 65535; 6559 range->max_retry = 65535;
6509 range->min_r_time = 1024; 6560 range->min_r_time = 1024;
6510 range->max_r_time = 65535 * 1024; 6561 range->max_r_time = 65535 * 1024;
6511 /* Experimental measurements - boundary 11/5.5 Mb/s */
6512 /* Note : with or without the (local->rssi), results
6513 * are somewhat different. - Jean II */
6514 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6515 if (local->rssi)
6516 range->avg_qual.level = 186; /* -70 dBm */
6517 else
6518 range->avg_qual.level = 176; /* -80 dBm */
6519 range->avg_qual.noise = 0;
6520 6562
6521 /* Event capability (kernel + driver) */ 6563 /* Event capability (kernel + driver) */
6522 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 6564 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -6676,12 +6718,18 @@ static int airo_get_aplist(struct net_device *dev,
6676 loseSync = 0; 6718 loseSync = 0;
6677 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN); 6719 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
6678 address[i].sa_family = ARPHRD_ETHER; 6720 address[i].sa_family = ARPHRD_ETHER;
6679 if (local->rssi) 6721 if (local->rssi) {
6680 qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm; 6722 qual[i].level = 0x100 - BSSList.dBm;
6681 else 6723 qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm );
6682 qual[i].level = (BSSList.rssi + 321) / 2; 6724 qual[i].updated = IW_QUAL_QUAL_UPDATED;
6683 qual[i].qual = qual[i].noise = 0; 6725 } else {
6684 qual[i].updated = 2; 6726 qual[i].level = (BSSList.dBm + 321) / 2;
6727 qual[i].qual = 0;
6728 qual[i].updated = IW_QUAL_QUAL_INVALID;
6729 }
6730 qual[i].noise = local->wstats.qual.noise;
6731 qual[i].updated = IW_QUAL_LEVEL_UPDATED
6732 | IW_QUAL_NOISE_UPDATED;
6685 if (BSSList.index == 0xffff) 6733 if (BSSList.index == 0xffff)
6686 break; 6734 break;
6687 } 6735 }
@@ -6760,7 +6808,7 @@ static int airo_set_scan(struct net_device *dev,
6760static inline char *airo_translate_scan(struct net_device *dev, 6808static inline char *airo_translate_scan(struct net_device *dev,
6761 char *current_ev, 6809 char *current_ev,
6762 char *end_buf, 6810 char *end_buf,
6763 BSSListRid *list) 6811 BSSListRid *bss)
6764{ 6812{
6765 struct airo_info *ai = dev->priv; 6813 struct airo_info *ai = dev->priv;
6766 struct iw_event iwe; /* Temporary buffer */ 6814 struct iw_event iwe; /* Temporary buffer */
@@ -6771,22 +6819,22 @@ static inline char *airo_translate_scan(struct net_device *dev,
6771 /* First entry *MUST* be the AP MAC address */ 6819 /* First entry *MUST* be the AP MAC address */
6772 iwe.cmd = SIOCGIWAP; 6820 iwe.cmd = SIOCGIWAP;
6773 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 6821 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
6774 memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN); 6822 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
6775 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 6823 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
6776 6824
6777 /* Other entries will be displayed in the order we give them */ 6825 /* Other entries will be displayed in the order we give them */
6778 6826
6779 /* Add the ESSID */ 6827 /* Add the ESSID */
6780 iwe.u.data.length = list->ssidLen; 6828 iwe.u.data.length = bss->ssidLen;
6781 if(iwe.u.data.length > 32) 6829 if(iwe.u.data.length > 32)
6782 iwe.u.data.length = 32; 6830 iwe.u.data.length = 32;
6783 iwe.cmd = SIOCGIWESSID; 6831 iwe.cmd = SIOCGIWESSID;
6784 iwe.u.data.flags = 1; 6832 iwe.u.data.flags = 1;
6785 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); 6833 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
6786 6834
6787 /* Add mode */ 6835 /* Add mode */
6788 iwe.cmd = SIOCGIWMODE; 6836 iwe.cmd = SIOCGIWMODE;
6789 capabilities = le16_to_cpu(list->cap); 6837 capabilities = le16_to_cpu(bss->cap);
6790 if(capabilities & (CAP_ESS | CAP_IBSS)) { 6838 if(capabilities & (CAP_ESS | CAP_IBSS)) {
6791 if(capabilities & CAP_ESS) 6839 if(capabilities & CAP_ESS)
6792 iwe.u.mode = IW_MODE_MASTER; 6840 iwe.u.mode = IW_MODE_MASTER;
@@ -6797,19 +6845,25 @@ static inline char *airo_translate_scan(struct net_device *dev,
6797 6845
6798 /* Add frequency */ 6846 /* Add frequency */
6799 iwe.cmd = SIOCGIWFREQ; 6847 iwe.cmd = SIOCGIWFREQ;
6800 iwe.u.freq.m = le16_to_cpu(list->dsChannel); 6848 iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
6801 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000; 6849 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
6802 iwe.u.freq.e = 1; 6850 iwe.u.freq.e = 1;
6803 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); 6851 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
6804 6852
6805 /* Add quality statistics */ 6853 /* Add quality statistics */
6806 iwe.cmd = IWEVQUAL; 6854 iwe.cmd = IWEVQUAL;
6807 if (ai->rssi) 6855 if (ai->rssi) {
6808 iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm; 6856 iwe.u.qual.level = 0x100 - bss->dBm;
6809 else 6857 iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm );
6810 iwe.u.qual.level = (list->rssi + 321) / 2; 6858 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED;
6811 iwe.u.qual.noise = 0; 6859 } else {
6812 iwe.u.qual.qual = 0; 6860 iwe.u.qual.level = (bss->dBm + 321) / 2;
6861 iwe.u.qual.qual = 0;
6862 iwe.u.qual.updated = IW_QUAL_QUAL_INVALID;
6863 }
6864 iwe.u.qual.noise = ai->wstats.qual.noise;
6865 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
6866 | IW_QUAL_NOISE_UPDATED;
6813 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 6867 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
6814 6868
6815 /* Add encryption capability */ 6869 /* Add encryption capability */
@@ -6819,7 +6873,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
6819 else 6873 else
6820 iwe.u.data.flags = IW_ENCODE_DISABLED; 6874 iwe.u.data.flags = IW_ENCODE_DISABLED;
6821 iwe.u.data.length = 0; 6875 iwe.u.data.length = 0;
6822 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); 6876 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
6823 6877
6824 /* Rate : stuffing multiple values in a single event require a bit 6878 /* Rate : stuffing multiple values in a single event require a bit
6825 * more of magic - Jean II */ 6879 * more of magic - Jean II */
@@ -6831,10 +6885,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
6831 /* Max 8 values */ 6885 /* Max 8 values */
6832 for(i = 0 ; i < 8 ; i++) { 6886 for(i = 0 ; i < 8 ; i++) {
6833 /* NULL terminated */ 6887 /* NULL terminated */
6834 if(list->rates[i] == 0) 6888 if(bss->rates[i] == 0)
6835 break; 6889 break;
6836 /* Bit rate given in 500 kb/s units (+ 0x80) */ 6890 /* Bit rate given in 500 kb/s units (+ 0x80) */
6837 iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000); 6891 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
6838 /* Add new value to event */ 6892 /* Add new value to event */
6839 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); 6893 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
6840 } 6894 }
@@ -7153,18 +7207,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
7153 /* The status */ 7207 /* The status */
7154 local->wstats.status = status_rid.mode; 7208 local->wstats.status = status_rid.mode;
7155 7209
7156 /* Signal quality and co. But where is the noise level ??? */ 7210 /* Signal quality and co */
7157 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); 7211 if (local->rssi) {
7158 if (local->rssi) 7212 local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality );
7159 local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm; 7213 /* normalizedSignalStrength appears to be a percentage */
7160 else 7214 local->wstats.qual.qual = status_rid.normalizedSignalStrength;
7215 } else {
7161 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; 7216 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
7217 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7218 }
7219 local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED;
7162 if (status_rid.len >= 124) { 7220 if (status_rid.len >= 124) {
7163 local->wstats.qual.noise = 256 - status_rid.noisedBm; 7221 local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7164 local->wstats.qual.updated = 7; 7222 local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED;
7165 } else { 7223 } else {
7166 local->wstats.qual.noise = 0; 7224 local->wstats.qual.noise = 0;
7167 local->wstats.qual.updated = 3; 7225 local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
7168 } 7226 }
7169 7227
7170 /* Packets discarded in the wireless adapter due to wireless 7228 /* Packets discarded in the wireless adapter due to wireless
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index a91b507e0a7a..a4ed28d9c783 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -321,6 +321,7 @@ static struct {
321 { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" }, 321 { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
322 { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" }, 322 { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
323 { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" }, 323 { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
324 { 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
324 { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" }, 325 { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
325 { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" }, 326 { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
326 { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" }, 327 { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 7cabb80a2e41..90d4d0ef3dd4 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
9obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 9obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
10obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o 10obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
11obj-$(CONFIG_LCS) += lcs.o cu3088.o 11obj-$(CONFIG_LCS) += lcs.o cu3088.o
12qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o 12obj-$(CONFIG_CLAW) += claw.o cu3088.o
13qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
13qeth-$(CONFIG_PROC_FS) += qeth_proc.o 14qeth-$(CONFIG_PROC_FS) += qeth_proc.o
14obj-$(CONFIG_QETH) += qeth.o 15obj-$(CONFIG_QETH) += qeth.o
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
index ef8883951720..7fe2ebd1792d 100644
--- a/drivers/s390/net/ctcdbug.h
+++ b/drivers/s390/net/ctcdbug.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.4 $) 3 * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)
4 * 4 *
5 * CTC / ESCON network driver - s390 dbf exploit. 5 * CTC / ESCON network driver - s390 dbf exploit.
6 * 6 *
@@ -9,7 +9,7 @@
9 * Author(s): Original Code written by 9 * Author(s): Original Code written by
10 * Peter Tiedemann (ptiedem@de.ibm.com) 10 * Peter Tiedemann (ptiedem@de.ibm.com)
11 * 11 *
12 * $Revision: 1.4 $ $Date: 2004/10/15 09:26:58 $ 12 * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -25,9 +25,11 @@
25 * along with this program; if not, write to the Free Software 25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28 28#ifndef _CTCDBUG_H_
29#define _CTCDBUG_H_
29 30
30#include <asm/debug.h> 31#include <asm/debug.h>
32#include "ctcmain.h"
31/** 33/**
32 * Debug Facility stuff 34 * Debug Facility stuff
33 */ 35 */
@@ -41,7 +43,7 @@
41#define CTC_DBF_DATA_LEN 128 43#define CTC_DBF_DATA_LEN 128
42#define CTC_DBF_DATA_INDEX 3 44#define CTC_DBF_DATA_INDEX 3
43#define CTC_DBF_DATA_NR_AREAS 1 45#define CTC_DBF_DATA_NR_AREAS 1
44#define CTC_DBF_DATA_LEVEL 2 46#define CTC_DBF_DATA_LEVEL 3
45 47
46#define CTC_DBF_TRACE_NAME "ctc_trace" 48#define CTC_DBF_TRACE_NAME "ctc_trace"
47#define CTC_DBF_TRACE_LEN 16 49#define CTC_DBF_TRACE_LEN 16
@@ -121,3 +123,5 @@ hex_dump(unsigned char *buf, size_t len)
121 printk("\n"); 123 printk("\n");
122} 124}
123 125
126
127#endif
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 7266bf5ea659..ff3e95e07e89 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ctcmain.c,v 1.72 2005/03/17 10:51:52 ptiedem Exp $ 2 * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
3 * 3 *
4 * CTC / ESCON network driver 4 * CTC / ESCON network driver
5 * 5 *
@@ -37,12 +37,11 @@
37 * along with this program; if not, write to the Free Software 37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 38 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
39 * 39 *
40 * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.72 $ 40 * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
41 * 41 *
42 */ 42 */
43 43
44#undef DEBUG 44#undef DEBUG
45
46#include <linux/module.h> 45#include <linux/module.h>
47#include <linux/init.h> 46#include <linux/init.h>
48#include <linux/kernel.h> 47#include <linux/kernel.h>
@@ -74,288 +73,13 @@
74#include "ctctty.h" 73#include "ctctty.h"
75#include "fsm.h" 74#include "fsm.h"
76#include "cu3088.h" 75#include "cu3088.h"
76
77#include "ctcdbug.h" 77#include "ctcdbug.h"
78#include "ctcmain.h"
78 79
79MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); 80MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
80MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver"); 81MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
81MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL");
82
83/**
84 * CCW commands, used in this driver.
85 */
86#define CCW_CMD_WRITE 0x01
87#define CCW_CMD_READ 0x02
88#define CCW_CMD_SET_EXTENDED 0xc3
89#define CCW_CMD_PREPARE 0xe3
90
91#define CTC_PROTO_S390 0
92#define CTC_PROTO_LINUX 1
93#define CTC_PROTO_LINUX_TTY 2
94#define CTC_PROTO_OS390 3
95#define CTC_PROTO_MAX 3
96
97#define CTC_BUFSIZE_LIMIT 65535
98#define CTC_BUFSIZE_DEFAULT 32768
99
100#define CTC_TIMEOUT_5SEC 5000
101
102#define CTC_INITIAL_BLOCKLEN 2
103
104#define READ 0
105#define WRITE 1
106
107#define CTC_ID_SIZE BUS_ID_SIZE+3
108
109
110struct ctc_profile {
111 unsigned long maxmulti;
112 unsigned long maxcqueue;
113 unsigned long doios_single;
114 unsigned long doios_multi;
115 unsigned long txlen;
116 unsigned long tx_time;
117 struct timespec send_stamp;
118};
119
120/**
121 * Definition of one channel
122 */
123struct channel {
124
125 /**
126 * Pointer to next channel in list.
127 */
128 struct channel *next;
129 char id[CTC_ID_SIZE];
130 struct ccw_device *cdev;
131
132 /**
133 * Type of this channel.
134 * CTC/A or Escon for valid channels.
135 */
136 enum channel_types type;
137
138 /**
139 * Misc. flags. See CHANNEL_FLAGS_... below
140 */
141 __u32 flags;
142
143 /**
144 * The protocol of this channel
145 */
146 __u16 protocol;
147
148 /**
149 * I/O and irq related stuff
150 */
151 struct ccw1 *ccw;
152 struct irb *irb;
153
154 /**
155 * RX/TX buffer size
156 */
157 int max_bufsize;
158
159 /**
160 * Transmit/Receive buffer.
161 */
162 struct sk_buff *trans_skb;
163
164 /**
165 * Universal I/O queue.
166 */
167 struct sk_buff_head io_queue;
168
169 /**
170 * TX queue for collecting skb's during busy.
171 */
172 struct sk_buff_head collect_queue;
173
174 /**
175 * Amount of data in collect_queue.
176 */
177 int collect_len;
178
179 /**
180 * spinlock for collect_queue and collect_len
181 */
182 spinlock_t collect_lock;
183
184 /**
185 * Timer for detecting unresposive
186 * I/O operations.
187 */
188 fsm_timer timer;
189
190 /**
191 * Retry counter for misc. operations.
192 */
193 int retry;
194
195 /**
196 * The finite state machine of this channel
197 */
198 fsm_instance *fsm;
199
200 /**
201 * The corresponding net_device this channel
202 * belongs to.
203 */
204 struct net_device *netdev;
205
206 struct ctc_profile prof;
207
208 unsigned char *trans_skb_data;
209
210 __u16 logflags;
211};
212
213#define CHANNEL_FLAGS_READ 0
214#define CHANNEL_FLAGS_WRITE 1
215#define CHANNEL_FLAGS_INUSE 2
216#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
217#define CHANNEL_FLAGS_FAILED 8
218#define CHANNEL_FLAGS_WAITIRQ 16
219#define CHANNEL_FLAGS_RWMASK 1
220#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
221
222#define LOG_FLAG_ILLEGALPKT 1
223#define LOG_FLAG_ILLEGALSIZE 2
224#define LOG_FLAG_OVERRUN 4
225#define LOG_FLAG_NOMEM 8
226
227#define CTC_LOGLEVEL_INFO 1
228#define CTC_LOGLEVEL_NOTICE 2
229#define CTC_LOGLEVEL_WARN 4
230#define CTC_LOGLEVEL_EMERG 8
231#define CTC_LOGLEVEL_ERR 16
232#define CTC_LOGLEVEL_DEBUG 32
233#define CTC_LOGLEVEL_CRIT 64
234
235#define CTC_LOGLEVEL_DEFAULT \
236(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
237
238#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)
239
240static int loglevel = CTC_LOGLEVEL_DEFAULT;
241
242#define ctc_pr_debug(fmt, arg...) \
243do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
244
245#define ctc_pr_info(fmt, arg...) \
246do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
247
248#define ctc_pr_notice(fmt, arg...) \
249do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
250
251#define ctc_pr_warn(fmt, arg...) \
252do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
253
254#define ctc_pr_emerg(fmt, arg...) \
255do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
256
257#define ctc_pr_err(fmt, arg...) \
258do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
259
260#define ctc_pr_crit(fmt, arg...) \
261do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
262
263/**
264 * Linked list of all detected channels.
265 */
266static struct channel *channels = NULL;
267
268struct ctc_priv {
269 struct net_device_stats stats;
270 unsigned long tbusy;
271 /**
272 * The finite state machine of this interface.
273 */
274 fsm_instance *fsm;
275 /**
276 * The protocol of this device
277 */
278 __u16 protocol;
279 /**
280 * Timer for restarting after I/O Errors
281 */
282 fsm_timer restart_timer;
283
284 int buffer_size;
285
286 struct channel *channel[2];
287};
288
289/**
290 * Definition of our link level header.
291 */
292struct ll_header {
293 __u16 length;
294 __u16 type;
295 __u16 unused;
296};
297#define LL_HEADER_LENGTH (sizeof(struct ll_header))
298
299/**
300 * Compatibility macros for busy handling
301 * of network devices.
302 */
303static __inline__ void
304ctc_clear_busy(struct net_device * dev)
305{
306 clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
307 if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
308 netif_wake_queue(dev);
309}
310
311static __inline__ int
312ctc_test_and_set_busy(struct net_device * dev)
313{
314 if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
315 netif_stop_queue(dev);
316 return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
317}
318
319/**
320 * Print Banner.
321 */
322static void
323print_banner(void)
324{
325 static int printed = 0;
326 char vbuf[] = "$Revision: 1.72 $";
327 char *version = vbuf;
328
329 if (printed)
330 return;
331 if ((version = strchr(version, ':'))) {
332 char *p = strchr(version + 1, '$');
333 if (p)
334 *p = '\0';
335 } else
336 version = " ??? ";
337 printk(KERN_INFO "CTC driver Version%s"
338#ifdef DEBUG
339 " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
340#endif
341 " initialized\n", version);
342 printed = 1;
343}
344
345/**
346 * Return type of a detected device.
347 */
348static enum channel_types
349get_channel_type(struct ccw_device_id *id)
350{
351 enum channel_types type = (enum channel_types) id->driver_info;
352
353 if (type == channel_type_ficon)
354 type = channel_type_escon;
355
356 return type;
357}
358
359/** 83/**
360 * States of the interface statemachine. 84 * States of the interface statemachine.
361 */ 85 */
@@ -371,7 +95,7 @@ enum dev_states {
371 /** 95 /**
372 * MUST be always the last element!! 96 * MUST be always the last element!!
373 */ 97 */
374 NR_DEV_STATES 98 CTC_NR_DEV_STATES
375}; 99};
376 100
377static const char *dev_state_names[] = { 101static const char *dev_state_names[] = {
@@ -399,7 +123,7 @@ enum dev_events {
399 /** 123 /**
400 * MUST be always the last element!! 124 * MUST be always the last element!!
401 */ 125 */
402 NR_DEV_EVENTS 126 CTC_NR_DEV_EVENTS
403}; 127};
404 128
405static const char *dev_event_names[] = { 129static const char *dev_event_names[] = {
@@ -476,40 +200,6 @@ enum ch_events {
476 NR_CH_EVENTS, 200 NR_CH_EVENTS,
477}; 201};
478 202
479static const char *ch_event_names[] = {
480 "ccw_device success",
481 "ccw_device busy",
482 "ccw_device enodev",
483 "ccw_device ioerr",
484 "ccw_device unknown",
485
486 "Status ATTN & BUSY",
487 "Status ATTN",
488 "Status BUSY",
489
490 "Unit check remote reset",
491 "Unit check remote system reset",
492 "Unit check TX timeout",
493 "Unit check TX parity",
494 "Unit check Hardware failure",
495 "Unit check RX parity",
496 "Unit check ZERO",
497 "Unit check Unknown",
498
499 "SubChannel check Unknown",
500
501 "Machine check failure",
502 "Machine check operational",
503
504 "IRQ normal",
505 "IRQ final",
506
507 "Timer",
508
509 "Start",
510 "Stop",
511};
512
513/** 203/**
514 * States of the channel statemachine. 204 * States of the channel statemachine.
515 */ 205 */
@@ -545,6 +235,87 @@ enum ch_states {
545 NR_CH_STATES, 235 NR_CH_STATES,
546}; 236};
547 237
238static int loglevel = CTC_LOGLEVEL_DEFAULT;
239
240/**
241 * Linked list of all detected channels.
242 */
243static struct channel *channels = NULL;
244
245/**
246 * Print Banner.
247 */
248static void
249print_banner(void)
250{
251 static int printed = 0;
252 char vbuf[] = "$Revision: 1.74 $";
253 char *version = vbuf;
254
255 if (printed)
256 return;
257 if ((version = strchr(version, ':'))) {
258 char *p = strchr(version + 1, '$');
259 if (p)
260 *p = '\0';
261 } else
262 version = " ??? ";
263 printk(KERN_INFO "CTC driver Version%s"
264#ifdef DEBUG
265 " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
266#endif
267 " initialized\n", version);
268 printed = 1;
269}
270
271/**
272 * Return type of a detected device.
273 */
274static enum channel_types
275get_channel_type(struct ccw_device_id *id)
276{
277 enum channel_types type = (enum channel_types) id->driver_info;
278
279 if (type == channel_type_ficon)
280 type = channel_type_escon;
281
282 return type;
283}
284
285static const char *ch_event_names[] = {
286 "ccw_device success",
287 "ccw_device busy",
288 "ccw_device enodev",
289 "ccw_device ioerr",
290 "ccw_device unknown",
291
292 "Status ATTN & BUSY",
293 "Status ATTN",
294 "Status BUSY",
295
296 "Unit check remote reset",
297 "Unit check remote system reset",
298 "Unit check TX timeout",
299 "Unit check TX parity",
300 "Unit check Hardware failure",
301 "Unit check RX parity",
302 "Unit check ZERO",
303 "Unit check Unknown",
304
305 "SubChannel check Unknown",
306
307 "Machine check failure",
308 "Machine check operational",
309
310 "IRQ normal",
311 "IRQ final",
312
313 "Timer",
314
315 "Start",
316 "Stop",
317};
318
548static const char *ch_state_names[] = { 319static const char *ch_state_names[] = {
549 "Idle", 320 "Idle",
550 "Stopped", 321 "Stopped",
@@ -1934,7 +1705,6 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
1934 ch->cdev = cdev; 1705 ch->cdev = cdev;
1935 snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id); 1706 snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id);
1936 ch->type = type; 1707 ch->type = type;
1937 loglevel = CTC_LOGLEVEL_DEFAULT;
1938 ch->fsm = init_fsm(ch->id, ch_state_names, 1708 ch->fsm = init_fsm(ch->id, ch_state_names,
1939 ch_event_names, NR_CH_STATES, NR_CH_EVENTS, 1709 ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
1940 ch_fsm, CH_FSM_LEN, GFP_KERNEL); 1710 ch_fsm, CH_FSM_LEN, GFP_KERNEL);
@@ -2697,6 +2467,7 @@ ctc_stats(struct net_device * dev)
2697/* 2467/*
2698 * sysfs attributes 2468 * sysfs attributes
2699 */ 2469 */
2470
2700static ssize_t 2471static ssize_t
2701buffer_show(struct device *dev, char *buf) 2472buffer_show(struct device *dev, char *buf)
2702{ 2473{
@@ -2715,57 +2486,61 @@ buffer_write(struct device *dev, const char *buf, size_t count)
2715 struct ctc_priv *priv; 2486 struct ctc_priv *priv;
2716 struct net_device *ndev; 2487 struct net_device *ndev;
2717 int bs1; 2488 int bs1;
2489 char buffer[16];
2718 2490
2719 DBF_TEXT(trace, 3, __FUNCTION__); 2491 DBF_TEXT(trace, 3, __FUNCTION__);
2492 DBF_TEXT(trace, 3, buf);
2720 priv = dev->driver_data; 2493 priv = dev->driver_data;
2721 if (!priv) 2494 if (!priv) {
2495 DBF_TEXT(trace, 3, "bfnopriv");
2722 return -ENODEV; 2496 return -ENODEV;
2497 }
2498
2499 sscanf(buf, "%u", &bs1);
2500 if (bs1 > CTC_BUFSIZE_LIMIT)
2501 goto einval;
2502 if (bs1 < (576 + LL_HEADER_LENGTH + 2))
2503 goto einval;
2504 priv->buffer_size = bs1; // just to overwrite the default
2505
2723 ndev = priv->channel[READ]->netdev; 2506 ndev = priv->channel[READ]->netdev;
2724 if (!ndev) 2507 if (!ndev) {
2508 DBF_TEXT(trace, 3, "bfnondev");
2725 return -ENODEV; 2509 return -ENODEV;
2726 sscanf(buf, "%u", &bs1); 2510 }
2727 2511
2728 if (bs1 > CTC_BUFSIZE_LIMIT)
2729 return -EINVAL;
2730 if ((ndev->flags & IFF_RUNNING) && 2512 if ((ndev->flags & IFF_RUNNING) &&
2731 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2))) 2513 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
2732 return -EINVAL; 2514 goto einval;
2733 if (bs1 < (576 + LL_HEADER_LENGTH + 2))
2734 return -EINVAL;
2735 2515
2736 priv->buffer_size = bs1; 2516 priv->channel[READ]->max_bufsize = bs1;
2737 priv->channel[READ]->max_bufsize = 2517 priv->channel[WRITE]->max_bufsize = bs1;
2738 priv->channel[WRITE]->max_bufsize = bs1;
2739 if (!(ndev->flags & IFF_RUNNING)) 2518 if (!(ndev->flags & IFF_RUNNING))
2740 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2; 2519 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
2741 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 2520 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
2742 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; 2521 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
2743 2522
2523 sprintf(buffer, "%d",priv->buffer_size);
2524 DBF_TEXT(trace, 3, buffer);
2744 return count; 2525 return count;
2745 2526
2527einval:
2528 DBF_TEXT(trace, 3, "buff_err");
2529 return -EINVAL;
2746} 2530}
2747 2531
2748static ssize_t 2532static ssize_t
2749loglevel_show(struct device *dev, char *buf) 2533loglevel_show(struct device *dev, char *buf)
2750{ 2534{
2751 struct ctc_priv *priv;
2752
2753 priv = dev->driver_data;
2754 if (!priv)
2755 return -ENODEV;
2756 return sprintf(buf, "%d\n", loglevel); 2535 return sprintf(buf, "%d\n", loglevel);
2757} 2536}
2758 2537
2759static ssize_t 2538static ssize_t
2760loglevel_write(struct device *dev, const char *buf, size_t count) 2539loglevel_write(struct device *dev, const char *buf, size_t count)
2761{ 2540{
2762 struct ctc_priv *priv;
2763 int ll1; 2541 int ll1;
2764 2542
2765 DBF_TEXT(trace, 5, __FUNCTION__); 2543 DBF_TEXT(trace, 5, __FUNCTION__);
2766 priv = dev->driver_data;
2767 if (!priv)
2768 return -ENODEV;
2769 sscanf(buf, "%i", &ll1); 2544 sscanf(buf, "%i", &ll1);
2770 2545
2771 if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0)) 2546 if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0))
@@ -2835,27 +2610,6 @@ stats_write(struct device *dev, const char *buf, size_t count)
2835 return count; 2610 return count;
2836} 2611}
2837 2612
2838static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
2839static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);
2840static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
2841
2842static int
2843ctc_add_attributes(struct device *dev)
2844{
2845// device_create_file(dev, &dev_attr_buffer);
2846 device_create_file(dev, &dev_attr_loglevel);
2847 device_create_file(dev, &dev_attr_stats);
2848 return 0;
2849}
2850
2851static void
2852ctc_remove_attributes(struct device *dev)
2853{
2854 device_remove_file(dev, &dev_attr_stats);
2855 device_remove_file(dev, &dev_attr_loglevel);
2856// device_remove_file(dev, &dev_attr_buffer);
2857}
2858
2859 2613
2860static void 2614static void
2861ctc_netdev_unregister(struct net_device * dev) 2615ctc_netdev_unregister(struct net_device * dev)
@@ -2899,52 +2653,6 @@ ctc_free_netdevice(struct net_device * dev, int free_dev)
2899#endif 2653#endif
2900} 2654}
2901 2655
2902/**
2903 * Initialize everything of the net device except the name and the
2904 * channel structs.
2905 */
2906static struct net_device *
2907ctc_init_netdevice(struct net_device * dev, int alloc_device,
2908 struct ctc_priv *privptr)
2909{
2910 if (!privptr)
2911 return NULL;
2912
2913 DBF_TEXT(setup, 3, __FUNCTION__);
2914 if (alloc_device) {
2915 dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
2916 if (!dev)
2917 return NULL;
2918 memset(dev, 0, sizeof (struct net_device));
2919 }
2920
2921 dev->priv = privptr;
2922 privptr->fsm = init_fsm("ctcdev", dev_state_names,
2923 dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
2924 dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
2925 if (privptr->fsm == NULL) {
2926 if (alloc_device)
2927 kfree(dev);
2928 return NULL;
2929 }
2930 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
2931 fsm_settimer(privptr->fsm, &privptr->restart_timer);
2932 if (dev->mtu == 0)
2933 dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
2934 dev->hard_start_xmit = ctc_tx;
2935 dev->open = ctc_open;
2936 dev->stop = ctc_close;
2937 dev->get_stats = ctc_stats;
2938 dev->change_mtu = ctc_change_mtu;
2939 dev->hard_header_len = LL_HEADER_LENGTH + 2;
2940 dev->addr_len = 0;
2941 dev->type = ARPHRD_SLIP;
2942 dev->tx_queue_len = 100;
2943 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
2944 SET_MODULE_OWNER(dev);
2945 return dev;
2946}
2947
2948static ssize_t 2656static ssize_t
2949ctc_proto_show(struct device *dev, char *buf) 2657ctc_proto_show(struct device *dev, char *buf)
2950{ 2658{
@@ -2977,7 +2685,6 @@ ctc_proto_store(struct device *dev, const char *buf, size_t count)
2977 return count; 2685 return count;
2978} 2686}
2979 2687
2980static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
2981 2688
2982static ssize_t 2689static ssize_t
2983ctc_type_show(struct device *dev, char *buf) 2690ctc_type_show(struct device *dev, char *buf)
@@ -2991,8 +2698,13 @@ ctc_type_show(struct device *dev, char *buf)
2991 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); 2698 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]);
2992} 2699}
2993 2700
2701static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
2702static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
2994static DEVICE_ATTR(type, 0444, ctc_type_show, NULL); 2703static DEVICE_ATTR(type, 0444, ctc_type_show, NULL);
2995 2704
2705static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);
2706static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
2707
2996static struct attribute *ctc_attr[] = { 2708static struct attribute *ctc_attr[] = {
2997 &dev_attr_protocol.attr, 2709 &dev_attr_protocol.attr,
2998 &dev_attr_type.attr, 2710 &dev_attr_type.attr,
@@ -3005,6 +2717,21 @@ static struct attribute_group ctc_attr_group = {
3005}; 2717};
3006 2718
3007static int 2719static int
2720ctc_add_attributes(struct device *dev)
2721{
2722 device_create_file(dev, &dev_attr_loglevel);
2723 device_create_file(dev, &dev_attr_stats);
2724 return 0;
2725}
2726
2727static void
2728ctc_remove_attributes(struct device *dev)
2729{
2730 device_remove_file(dev, &dev_attr_stats);
2731 device_remove_file(dev, &dev_attr_loglevel);
2732}
2733
2734static int
3008ctc_add_files(struct device *dev) 2735ctc_add_files(struct device *dev)
3009{ 2736{
3010 pr_debug("%s() called\n", __FUNCTION__); 2737 pr_debug("%s() called\n", __FUNCTION__);
@@ -3028,15 +2755,15 @@ ctc_remove_files(struct device *dev)
3028 * 2755 *
3029 * @returns 0 on success, !0 on failure. 2756 * @returns 0 on success, !0 on failure.
3030 */ 2757 */
3031
3032static int 2758static int
3033ctc_probe_device(struct ccwgroup_device *cgdev) 2759ctc_probe_device(struct ccwgroup_device *cgdev)
3034{ 2760{
3035 struct ctc_priv *priv; 2761 struct ctc_priv *priv;
3036 int rc; 2762 int rc;
2763 char buffer[16];
3037 2764
3038 pr_debug("%s() called\n", __FUNCTION__); 2765 pr_debug("%s() called\n", __FUNCTION__);
3039 DBF_TEXT(trace, 3, __FUNCTION__); 2766 DBF_TEXT(setup, 3, __FUNCTION__);
3040 2767
3041 if (!get_device(&cgdev->dev)) 2768 if (!get_device(&cgdev->dev))
3042 return -ENODEV; 2769 return -ENODEV;
@@ -3060,10 +2787,70 @@ ctc_probe_device(struct ccwgroup_device *cgdev)
3060 cgdev->cdev[1]->handler = ctc_irq_handler; 2787 cgdev->cdev[1]->handler = ctc_irq_handler;
3061 cgdev->dev.driver_data = priv; 2788 cgdev->dev.driver_data = priv;
3062 2789
2790 sprintf(buffer, "%p", priv);
2791 DBF_TEXT(data, 3, buffer);
2792
2793 sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv));
2794 DBF_TEXT(data, 3, buffer);
2795
2796 sprintf(buffer, "%p", &channels);
2797 DBF_TEXT(data, 3, buffer);
2798
2799 sprintf(buffer, "%u", (unsigned int)sizeof(struct channel));
2800 DBF_TEXT(data, 3, buffer);
2801
3063 return 0; 2802 return 0;
3064} 2803}
3065 2804
3066/** 2805/**
2806 * Initialize everything of the net device except the name and the
2807 * channel structs.
2808 */
2809static struct net_device *
2810ctc_init_netdevice(struct net_device * dev, int alloc_device,
2811 struct ctc_priv *privptr)
2812{
2813 if (!privptr)
2814 return NULL;
2815
2816 DBF_TEXT(setup, 3, __FUNCTION__);
2817
2818 if (alloc_device) {
2819 dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
2820 if (!dev)
2821 return NULL;
2822 memset(dev, 0, sizeof (struct net_device));
2823 }
2824
2825 dev->priv = privptr;
2826 privptr->fsm = init_fsm("ctcdev", dev_state_names,
2827 dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS,
2828 dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
2829 if (privptr->fsm == NULL) {
2830 if (alloc_device)
2831 kfree(dev);
2832 return NULL;
2833 }
2834 fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
2835 fsm_settimer(privptr->fsm, &privptr->restart_timer);
2836 if (dev->mtu == 0)
2837 dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
2838 dev->hard_start_xmit = ctc_tx;
2839 dev->open = ctc_open;
2840 dev->stop = ctc_close;
2841 dev->get_stats = ctc_stats;
2842 dev->change_mtu = ctc_change_mtu;
2843 dev->hard_header_len = LL_HEADER_LENGTH + 2;
2844 dev->addr_len = 0;
2845 dev->type = ARPHRD_SLIP;
2846 dev->tx_queue_len = 100;
2847 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
2848 SET_MODULE_OWNER(dev);
2849 return dev;
2850}
2851
2852
2853/**
3067 * 2854 *
3068 * Setup an interface. 2855 * Setup an interface.
3069 * 2856 *
@@ -3081,6 +2868,7 @@ ctc_new_device(struct ccwgroup_device *cgdev)
3081 struct ctc_priv *privptr; 2868 struct ctc_priv *privptr;
3082 struct net_device *dev; 2869 struct net_device *dev;
3083 int ret; 2870 int ret;
2871 char buffer[16];
3084 2872
3085 pr_debug("%s() called\n", __FUNCTION__); 2873 pr_debug("%s() called\n", __FUNCTION__);
3086 DBF_TEXT(setup, 3, __FUNCTION__); 2874 DBF_TEXT(setup, 3, __FUNCTION__);
@@ -3089,6 +2877,9 @@ ctc_new_device(struct ccwgroup_device *cgdev)
3089 if (!privptr) 2877 if (!privptr)
3090 return -ENODEV; 2878 return -ENODEV;
3091 2879
2880 sprintf(buffer, "%d", privptr->buffer_size);
2881 DBF_TEXT(setup, 3, buffer);
2882
3092 type = get_channel_type(&cgdev->cdev[0]->id); 2883 type = get_channel_type(&cgdev->cdev[0]->id);
3093 2884
3094 snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id); 2885 snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
@@ -3177,9 +2968,10 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
3177 struct ctc_priv *priv; 2968 struct ctc_priv *priv;
3178 struct net_device *ndev; 2969 struct net_device *ndev;
3179 2970
3180 DBF_TEXT(trace, 3, __FUNCTION__); 2971 DBF_TEXT(setup, 3, __FUNCTION__);
3181 pr_debug("%s() called\n", __FUNCTION__); 2972 pr_debug("%s() called\n", __FUNCTION__);
3182 2973
2974
3183 priv = cgdev->dev.driver_data; 2975 priv = cgdev->dev.driver_data;
3184 ndev = NULL; 2976 ndev = NULL;
3185 if (!priv) 2977 if (!priv)
@@ -3215,7 +3007,6 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
3215 channel_remove(priv->channel[READ]); 3007 channel_remove(priv->channel[READ]);
3216 if (priv->channel[WRITE]) 3008 if (priv->channel[WRITE])
3217 channel_remove(priv->channel[WRITE]); 3009 channel_remove(priv->channel[WRITE]);
3218
3219 priv->channel[READ] = priv->channel[WRITE] = NULL; 3010 priv->channel[READ] = priv->channel[WRITE] = NULL;
3220 3011
3221 return 0; 3012 return 0;
@@ -3228,7 +3019,7 @@ ctc_remove_device(struct ccwgroup_device *cgdev)
3228 struct ctc_priv *priv; 3019 struct ctc_priv *priv;
3229 3020
3230 pr_debug("%s() called\n", __FUNCTION__); 3021 pr_debug("%s() called\n", __FUNCTION__);
3231 DBF_TEXT(trace, 3, __FUNCTION__); 3022 DBF_TEXT(setup, 3, __FUNCTION__);
3232 3023
3233 priv = cgdev->dev.driver_data; 3024 priv = cgdev->dev.driver_data;
3234 if (!priv) 3025 if (!priv)
@@ -3265,6 +3056,7 @@ static struct ccwgroup_driver ctc_group_driver = {
3265static void __exit 3056static void __exit
3266ctc_exit(void) 3057ctc_exit(void)
3267{ 3058{
3059 DBF_TEXT(setup, 3, __FUNCTION__);
3268 unregister_cu3088_discipline(&ctc_group_driver); 3060 unregister_cu3088_discipline(&ctc_group_driver);
3269 ctc_tty_cleanup(); 3061 ctc_tty_cleanup();
3270 ctc_unregister_dbf_views(); 3062 ctc_unregister_dbf_views();
@@ -3282,6 +3074,10 @@ ctc_init(void)
3282{ 3074{
3283 int ret = 0; 3075 int ret = 0;
3284 3076
3077 loglevel = CTC_LOGLEVEL_DEFAULT;
3078
3079 DBF_TEXT(setup, 3, __FUNCTION__);
3080
3285 print_banner(); 3081 print_banner();
3286 3082
3287 ret = ctc_register_dbf_views(); 3083 ret = ctc_register_dbf_views();
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
new file mode 100644
index 000000000000..ba3605f16335
--- /dev/null
+++ b/drivers/s390/net/ctcmain.h
@@ -0,0 +1,276 @@
1/*
2 * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $
3 *
4 * CTC / ESCON network driver
5 *
6 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
8 Peter Tiedemann (ptiedem@de.ibm.com)
9 *
10 *
11 * Documentation used:
12 * - Principles of Operation (IBM doc#: SA22-7201-06)
13 * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)
14 * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)
15 * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)
16 * - ESCON I/O Interface (IBM doc#: SA22-7202-029
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $
33 *
34 */
35
36#ifndef _CTCMAIN_H_
37#define _CTCMAIN_H_
38
39#include <asm/ccwdev.h>
40#include <asm/ccwgroup.h>
41
42#include "ctctty.h"
43#include "fsm.h"
44#include "cu3088.h"
45
46
47/**
48 * CCW commands, used in this driver.
49 */
50#define CCW_CMD_WRITE 0x01
51#define CCW_CMD_READ 0x02
52#define CCW_CMD_SET_EXTENDED 0xc3
53#define CCW_CMD_PREPARE 0xe3
54
55#define CTC_PROTO_S390 0
56#define CTC_PROTO_LINUX 1
57#define CTC_PROTO_LINUX_TTY 2
58#define CTC_PROTO_OS390 3
59#define CTC_PROTO_MAX 3
60
61#define CTC_BUFSIZE_LIMIT 65535
62#define CTC_BUFSIZE_DEFAULT 32768
63
64#define CTC_TIMEOUT_5SEC 5000
65
66#define CTC_INITIAL_BLOCKLEN 2
67
68#define READ 0
69#define WRITE 1
70
71#define CTC_ID_SIZE BUS_ID_SIZE+3
72
73
74struct ctc_profile {
75 unsigned long maxmulti;
76 unsigned long maxcqueue;
77 unsigned long doios_single;
78 unsigned long doios_multi;
79 unsigned long txlen;
80 unsigned long tx_time;
81 struct timespec send_stamp;
82};
83
84/**
85 * Definition of one channel
86 */
87struct channel {
88
89 /**
90 * Pointer to next channel in list.
91 */
92 struct channel *next;
93 char id[CTC_ID_SIZE];
94 struct ccw_device *cdev;
95
96 /**
97 * Type of this channel.
98 * CTC/A or Escon for valid channels.
99 */
100 enum channel_types type;
101
102 /**
103 * Misc. flags. See CHANNEL_FLAGS_... below
104 */
105 __u32 flags;
106
107 /**
108 * The protocol of this channel
109 */
110 __u16 protocol;
111
112 /**
113 * I/O and irq related stuff
114 */
115 struct ccw1 *ccw;
116 struct irb *irb;
117
118 /**
119 * RX/TX buffer size
120 */
121 int max_bufsize;
122
123 /**
124 * Transmit/Receive buffer.
125 */
126 struct sk_buff *trans_skb;
127
128 /**
129 * Universal I/O queue.
130 */
131 struct sk_buff_head io_queue;
132
133 /**
134 * TX queue for collecting skb's during busy.
135 */
136 struct sk_buff_head collect_queue;
137
138 /**
139 * Amount of data in collect_queue.
140 */
141 int collect_len;
142
143 /**
144 * spinlock for collect_queue and collect_len
145 */
146 spinlock_t collect_lock;
147
148 /**
149 * Timer for detecting unresposive
150 * I/O operations.
151 */
152 fsm_timer timer;
153
154 /**
155 * Retry counter for misc. operations.
156 */
157 int retry;
158
159 /**
160 * The finite state machine of this channel
161 */
162 fsm_instance *fsm;
163
164 /**
165 * The corresponding net_device this channel
166 * belongs to.
167 */
168 struct net_device *netdev;
169
170 struct ctc_profile prof;
171
172 unsigned char *trans_skb_data;
173
174 __u16 logflags;
175};
176
177#define CHANNEL_FLAGS_READ 0
178#define CHANNEL_FLAGS_WRITE 1
179#define CHANNEL_FLAGS_INUSE 2
180#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
181#define CHANNEL_FLAGS_FAILED 8
182#define CHANNEL_FLAGS_WAITIRQ 16
183#define CHANNEL_FLAGS_RWMASK 1
184#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
185
186#define LOG_FLAG_ILLEGALPKT 1
187#define LOG_FLAG_ILLEGALSIZE 2
188#define LOG_FLAG_OVERRUN 4
189#define LOG_FLAG_NOMEM 8
190
191#define CTC_LOGLEVEL_INFO 1
192#define CTC_LOGLEVEL_NOTICE 2
193#define CTC_LOGLEVEL_WARN 4
194#define CTC_LOGLEVEL_EMERG 8
195#define CTC_LOGLEVEL_ERR 16
196#define CTC_LOGLEVEL_DEBUG 32
197#define CTC_LOGLEVEL_CRIT 64
198
199#define CTC_LOGLEVEL_DEFAULT \
200(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
201
202#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)
203
204#define ctc_pr_debug(fmt, arg...) \
205do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
206
207#define ctc_pr_info(fmt, arg...) \
208do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
209
210#define ctc_pr_notice(fmt, arg...) \
211do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
212
213#define ctc_pr_warn(fmt, arg...) \
214do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
215
216#define ctc_pr_emerg(fmt, arg...) \
217do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
218
219#define ctc_pr_err(fmt, arg...) \
220do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
221
222#define ctc_pr_crit(fmt, arg...) \
223do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
224
225struct ctc_priv {
226 struct net_device_stats stats;
227 unsigned long tbusy;
228 /**
229 * The finite state machine of this interface.
230 */
231 fsm_instance *fsm;
232 /**
233 * The protocol of this device
234 */
235 __u16 protocol;
236 /**
237 * Timer for restarting after I/O Errors
238 */
239 fsm_timer restart_timer;
240
241 int buffer_size;
242
243 struct channel *channel[2];
244};
245
246/**
247 * Definition of our link level header.
248 */
249struct ll_header {
250 __u16 length;
251 __u16 type;
252 __u16 unused;
253};
254#define LL_HEADER_LENGTH (sizeof(struct ll_header))
255
256/**
257 * Compatibility macros for busy handling
258 * of network devices.
259 */
260static __inline__ void
261ctc_clear_busy(struct net_device * dev)
262{
263 clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
264 if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
265 netif_wake_queue(dev);
266}
267
268static __inline__ int
269ctc_test_and_set_busy(struct net_device * dev)
270{
271 if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
272 netif_stop_queue(dev);
273 return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
274}
275
276#endif
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
index 9257d60c7833..3080393e823d 100644
--- a/drivers/s390/net/ctctty.c
+++ b/drivers/s390/net/ctctty.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ctctty.c,v 1.26 2004/08/04 11:06:55 mschwide Exp $ 2 * $Id: ctctty.c,v 1.29 2005/04/05 08:50:44 mschwide Exp $
3 * 3 *
4 * CTC / ESCON network driver, tty interface. 4 * CTC / ESCON network driver, tty interface.
5 * 5 *
@@ -1056,8 +1056,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
1056 info->tty = 0; 1056 info->tty = 0;
1057 tty->closing = 0; 1057 tty->closing = 0;
1058 if (info->blocked_open) { 1058 if (info->blocked_open) {
1059 set_current_state(TASK_INTERRUPTIBLE); 1059 msleep_interruptible(500);
1060 schedule_timeout(HZ/2);
1061 wake_up_interruptible(&info->open_wait); 1060 wake_up_interruptible(&info->open_wait);
1062 } 1061 }
1063 info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING); 1062 info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index 1b0a9f16024c..0075894c71db 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cu3088.c,v 1.34 2004/06/15 13:16:27 pavlic Exp $ 2 * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $
3 * 3 *
4 * CTC / LCS ccw_device driver 4 * CTC / LCS ccw_device driver
5 * 5 *
@@ -39,6 +39,7 @@ const char *cu3088_type[] = {
39 "FICON channel", 39 "FICON channel",
40 "P390 LCS card", 40 "P390 LCS card",
41 "OSA LCS card", 41 "OSA LCS card",
42 "CLAW channel device",
42 "unknown channel type", 43 "unknown channel type",
43 "unsupported channel type", 44 "unsupported channel type",
44}; 45};
@@ -51,6 +52,7 @@ static struct ccw_device_id cu3088_ids[] = {
51 { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, 52 { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
52 { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 }, 53 { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 },
53 { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, 54 { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
55 { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw },
54 { /* end of list */ } 56 { /* end of list */ }
55}; 57};
56 58
diff --git a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h
index 0ec49a8b3adc..1753661f702a 100644
--- a/drivers/s390/net/cu3088.h
+++ b/drivers/s390/net/cu3088.h
@@ -23,6 +23,9 @@ enum channel_types {
23 /* Device is a OSA2 card */ 23 /* Device is a OSA2 card */
24 channel_type_osa2, 24 channel_type_osa2,
25 25
26 /* Device is a CLAW channel device */
27 channel_type_claw,
28
26 /* Device is a channel, but we don't know 29 /* Device is a channel, but we don't know
27 * anything about it */ 30 * anything about it */
28 channel_type_unknown, 31 channel_type_unknown,
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index 1ac6563ee3e0..e08e74e16124 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: iucv.c,v 1.43 2005/02/09 14:47:43 braunu Exp $ 2 * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $
3 * 3 *
4 * IUCV network driver 4 * IUCV network driver
5 * 5 *
@@ -29,7 +29,7 @@
29 * along with this program; if not, write to the Free Software 29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * 31 *
32 * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.43 $ 32 * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.45 $
33 * 33 *
34 */ 34 */
35 35
@@ -355,7 +355,7 @@ do { \
355static void 355static void
356iucv_banner(void) 356iucv_banner(void)
357{ 357{
358 char vbuf[] = "$Revision: 1.43 $"; 358 char vbuf[] = "$Revision: 1.45 $";
359 char *version = vbuf; 359 char *version = vbuf;
360 360
361 if ((version = strchr(version, ':'))) { 361 if ((version = strchr(version, ':'))) {
@@ -2553,12 +2553,12 @@ EXPORT_SYMBOL (iucv_resume);
2553#endif 2553#endif
2554EXPORT_SYMBOL (iucv_reply_prmmsg); 2554EXPORT_SYMBOL (iucv_reply_prmmsg);
2555EXPORT_SYMBOL (iucv_send); 2555EXPORT_SYMBOL (iucv_send);
2556#if 0
2557EXPORT_SYMBOL (iucv_send2way); 2556EXPORT_SYMBOL (iucv_send2way);
2558EXPORT_SYMBOL (iucv_send2way_array); 2557EXPORT_SYMBOL (iucv_send2way_array);
2559EXPORT_SYMBOL (iucv_send_array);
2560EXPORT_SYMBOL (iucv_send2way_prmmsg); 2558EXPORT_SYMBOL (iucv_send2way_prmmsg);
2561EXPORT_SYMBOL (iucv_send2way_prmmsg_array); 2559EXPORT_SYMBOL (iucv_send2way_prmmsg_array);
2560#if 0
2561EXPORT_SYMBOL (iucv_send_array);
2562EXPORT_SYMBOL (iucv_send_prmmsg); 2562EXPORT_SYMBOL (iucv_send_prmmsg);
2563EXPORT_SYMBOL (iucv_setmask); 2563EXPORT_SYMBOL (iucv_setmask);
2564#endif 2564#endif
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 0f76e945b984..cccfed248e70 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -11,7 +11,7 @@
11 * Frank Pavlic (pavlic@de.ibm.com) and 11 * Frank Pavlic (pavlic@de.ibm.com) and
12 * Martin Schwidefsky <schwidefsky@de.ibm.com> 12 * Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * 13 *
14 * $Revision: 1.96 $ $Date: 2004/11/11 13:42:33 $ 14 * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@
59/** 59/**
60 * initialization string for output 60 * initialization string for output
61 */ 61 */
62#define VERSION_LCS_C "$Revision: 1.96 $" 62#define VERSION_LCS_C "$Revision: 1.98 $"
63 63
64static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; 64static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
65static char debug_buffer[255]; 65static char debug_buffer[255];
@@ -1098,14 +1098,6 @@ lcs_check_multicast_support(struct lcs_card *card)
1098 PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n"); 1098 PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n");
1099 return -EOPNOTSUPP; 1099 return -EOPNOTSUPP;
1100 } 1100 }
1101 /* Print out supported assists: IPv6 */
1102 PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name,
1103 (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ?
1104 "with" : "without");
1105 /* Print out supported assist: Multicast */
1106 PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name,
1107 (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ?
1108 "with" : "without");
1109 if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) 1101 if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT)
1110 return 0; 1102 return 0;
1111 return -EOPNOTSUPP; 1103 return -EOPNOTSUPP;
@@ -1160,7 +1152,7 @@ list_modified:
1160 } 1152 }
1161 } 1153 }
1162 /* re-insert all entries from the failed_list into ipm_list */ 1154 /* re-insert all entries from the failed_list into ipm_list */
1163 list_for_each_entry(ipm, &failed_list, list) { 1155 list_for_each_entry_safe(ipm, tmp, &failed_list, list) {
1164 list_del_init(&ipm->list); 1156 list_del_init(&ipm->list);
1165 list_add_tail(&ipm->list, &card->ipm_list); 1157 list_add_tail(&ipm->list, &card->ipm_list);
1166 } 1158 }
@@ -2198,30 +2190,39 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
2198 if (!dev) 2190 if (!dev)
2199 goto out; 2191 goto out;
2200 card->dev = dev; 2192 card->dev = dev;
2201netdev_out:
2202 card->dev->priv = card; 2193 card->dev->priv = card;
2203 card->dev->open = lcs_open_device; 2194 card->dev->open = lcs_open_device;
2204 card->dev->stop = lcs_stop_device; 2195 card->dev->stop = lcs_stop_device;
2205 card->dev->hard_start_xmit = lcs_start_xmit; 2196 card->dev->hard_start_xmit = lcs_start_xmit;
2206 card->dev->get_stats = lcs_getstats; 2197 card->dev->get_stats = lcs_getstats;
2207 SET_MODULE_OWNER(dev); 2198 SET_MODULE_OWNER(dev);
2208 if (lcs_register_netdev(ccwgdev) != 0)
2209 goto out;
2210 memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); 2199 memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
2211#ifdef CONFIG_IP_MULTICAST 2200#ifdef CONFIG_IP_MULTICAST
2212 if (!lcs_check_multicast_support(card)) 2201 if (!lcs_check_multicast_support(card))
2213 card->dev->set_multicast_list = lcs_set_multicast_list; 2202 card->dev->set_multicast_list = lcs_set_multicast_list;
2214#endif 2203#endif
2215 netif_stop_queue(card->dev); 2204netdev_out:
2216 lcs_set_allowed_threads(card,0xffffffff); 2205 lcs_set_allowed_threads(card,0xffffffff);
2217 if (recover_state == DEV_STATE_RECOVER) { 2206 if (recover_state == DEV_STATE_RECOVER) {
2218 lcs_set_multicast_list(card->dev); 2207 lcs_set_multicast_list(card->dev);
2219 card->dev->flags |= IFF_UP; 2208 card->dev->flags |= IFF_UP;
2220 netif_wake_queue(card->dev); 2209 netif_wake_queue(card->dev);
2221 card->state = DEV_STATE_UP; 2210 card->state = DEV_STATE_UP;
2222 } else 2211 } else {
2223 lcs_stopcard(card); 2212 lcs_stopcard(card);
2213 }
2224 2214
2215 if (lcs_register_netdev(ccwgdev) != 0)
2216 goto out;
2217
2218 /* Print out supported assists: IPv6 */
2219 PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name,
2220 (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ?
2221 "with" : "without");
2222 /* Print out supported assist: Multicast */
2223 PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name,
2224 (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ?
2225 "with" : "without");
2225 return 0; 2226 return 0;
2226out: 2227out:
2227 2228
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index a341041a6cf7..a755b57db46b 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -24,7 +24,7 @@
24 24
25#include "qeth_mpc.h" 25#include "qeth_mpc.h"
26 26
27#define VERSION_QETH_H "$Revision: 1.135 $" 27#define VERSION_QETH_H "$Revision: 1.139 $"
28 28
29#ifdef CONFIG_QETH_IPV6 29#ifdef CONFIG_QETH_IPV6
30#define QETH_VERSION_IPV6 ":IPv6" 30#define QETH_VERSION_IPV6 ":IPv6"
@@ -288,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
288#define QETH_TX_TIMEOUT 100 * HZ 288#define QETH_TX_TIMEOUT 100 * HZ
289#define QETH_HEADER_SIZE 32 289#define QETH_HEADER_SIZE 32
290#define MAX_PORTNO 15 290#define MAX_PORTNO 15
291#define QETH_FAKE_LL_LEN ETH_HLEN 291#define QETH_FAKE_LL_LEN_ETH ETH_HLEN
292#define QETH_FAKE_LL_LEN_TR (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc))
292#define QETH_FAKE_LL_V6_ADDR_POS 24 293#define QETH_FAKE_LL_V6_ADDR_POS 24
293 294
294/*IPv6 address autoconfiguration stuff*/ 295/*IPv6 address autoconfiguration stuff*/
@@ -369,6 +370,25 @@ struct qeth_hdr {
369 } hdr; 370 } hdr;
370} __attribute__ ((packed)); 371} __attribute__ ((packed));
371 372
373/*TCP Segmentation Offload header*/
374struct qeth_hdr_ext_tso {
375 __u16 hdr_tot_len;
376 __u8 imb_hdr_no;
377 __u8 reserved;
378 __u8 hdr_type;
379 __u8 hdr_version;
380 __u16 hdr_len;
381 __u32 payload_len;
382 __u16 mss;
383 __u16 dg_hdr_len;
384 __u8 padding[16];
385} __attribute__ ((packed));
386
387struct qeth_hdr_tso {
388 struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/
389 struct qeth_hdr_ext_tso ext;
390} __attribute__ ((packed));
391
372 392
373/* flags for qeth_hdr.flags */ 393/* flags for qeth_hdr.flags */
374#define QETH_HDR_PASSTHRU 0x10 394#define QETH_HDR_PASSTHRU 0x10
@@ -866,6 +886,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
866 return hdr; 886 return hdr;
867} 887}
868 888
889
869inline static int 890inline static int
870qeth_get_hlen(__u8 link_type) 891qeth_get_hlen(__u8 link_type)
871{ 892{
@@ -873,19 +894,19 @@ qeth_get_hlen(__u8 link_type)
873 switch (link_type) { 894 switch (link_type) {
874 case QETH_LINK_TYPE_HSTR: 895 case QETH_LINK_TYPE_HSTR:
875 case QETH_LINK_TYPE_LANE_TR: 896 case QETH_LINK_TYPE_LANE_TR:
876 return sizeof(struct qeth_hdr) + TR_HLEN; 897 return sizeof(struct qeth_hdr_tso) + TR_HLEN;
877 default: 898 default:
878#ifdef CONFIG_QETH_VLAN 899#ifdef CONFIG_QETH_VLAN
879 return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN; 900 return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN;
880#else 901#else
881 return sizeof(struct qeth_hdr) + ETH_HLEN; 902 return sizeof(struct qeth_hdr_tso) + ETH_HLEN;
882#endif 903#endif
883 } 904 }
884#else /* CONFIG_QETH_IPV6 */ 905#else /* CONFIG_QETH_IPV6 */
885#ifdef CONFIG_QETH_VLAN 906#ifdef CONFIG_QETH_VLAN
886 return sizeof(struct qeth_hdr) + VLAN_HLEN; 907 return sizeof(struct qeth_hdr_tso) + VLAN_HLEN;
887#else 908#else
888 return sizeof(struct qeth_hdr); 909 return sizeof(struct qeth_hdr_tso);
889#endif 910#endif
890#endif /* CONFIG_QETH_IPV6 */ 911#endif /* CONFIG_QETH_IPV6 */
891} 912}
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 7ee1c06ed68a..f94f1f25eec6 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.11 $) 3 * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.13 $)
4 * 4 *
5 * Enhanced Device Driver Packing (EDDP) support for the qeth driver. 5 * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
6 * 6 *
@@ -8,7 +8,7 @@
8 * 8 *
9 * Author(s): Thomas Spatzier <tspat@de.ibm.com> 9 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
10 * 10 *
11 * $Revision: 1.11 $ $Date: 2005/03/24 09:04:18 $ 11 * $Revision: 1.13 $ $Date: 2005/05/04 20:19:18 $
12 * 12 *
13 */ 13 */
14#include <linux/config.h> 14#include <linux/config.h>
@@ -85,7 +85,7 @@ void
85qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf) 85qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
86{ 86{
87 struct qeth_eddp_context_reference *ref; 87 struct qeth_eddp_context_reference *ref;
88 88
89 QETH_DBF_TEXT(trace, 6, "eddprctx"); 89 QETH_DBF_TEXT(trace, 6, "eddprctx");
90 while (!list_empty(&buf->ctx_list)){ 90 while (!list_empty(&buf->ctx_list)){
91 ref = list_entry(buf->ctx_list.next, 91 ref = list_entry(buf->ctx_list.next,
@@ -139,7 +139,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
139 "buffer!\n"); 139 "buffer!\n");
140 goto out; 140 goto out;
141 } 141 }
142 } 142 }
143 /* check if the whole next skb fits into current buffer */ 143 /* check if the whole next skb fits into current buffer */
144 if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) - 144 if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
145 buf->next_element_to_fill) 145 buf->next_element_to_fill)
@@ -152,7 +152,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
152 * and increment ctx's refcnt */ 152 * and increment ctx's refcnt */
153 must_refcnt = 1; 153 must_refcnt = 1;
154 continue; 154 continue;
155 } 155 }
156 if (must_refcnt){ 156 if (must_refcnt){
157 must_refcnt = 0; 157 must_refcnt = 0;
158 if (qeth_eddp_buf_ref_context(buf, ctx)){ 158 if (qeth_eddp_buf_ref_context(buf, ctx)){
@@ -202,40 +202,29 @@ out:
202 return flush_cnt; 202 return flush_cnt;
203} 203}
204 204
205static inline int
206qeth_get_skb_data_len(struct sk_buff *skb)
207{
208 int len = skb->len;
209 int i;
210
211 for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i)
212 len -= skb_shinfo(skb)->frags[i].size;
213 return len;
214}
215
216static inline void 205static inline void
217qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, 206qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
218 struct qeth_eddp_data *eddp) 207 struct qeth_eddp_data *eddp, int data_len)
219{ 208{
220 u8 *page; 209 u8 *page;
221 int page_remainder; 210 int page_remainder;
222 int page_offset; 211 int page_offset;
223 int hdr_len; 212 int pkt_len;
224 struct qeth_eddp_element *element; 213 struct qeth_eddp_element *element;
225 214
226 QETH_DBF_TEXT(trace, 5, "eddpcrsh"); 215 QETH_DBF_TEXT(trace, 5, "eddpcrsh");
227 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; 216 page = ctx->pages[ctx->offset >> PAGE_SHIFT];
228 page_offset = ctx->offset % PAGE_SIZE; 217 page_offset = ctx->offset % PAGE_SIZE;
229 element = &ctx->elements[ctx->num_elements]; 218 element = &ctx->elements[ctx->num_elements];
230 hdr_len = eddp->nhl + eddp->thl; 219 pkt_len = eddp->nhl + eddp->thl + data_len;
231 /* FIXME: layer2 and VLAN !!! */ 220 /* FIXME: layer2 and VLAN !!! */
232 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) 221 if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
233 hdr_len += ETH_HLEN; 222 pkt_len += ETH_HLEN;
234 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) 223 if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
235 hdr_len += VLAN_HLEN; 224 pkt_len += VLAN_HLEN;
236 /* does complete header fit in current page ? */ 225 /* does complete packet fit in current page ? */
237 page_remainder = PAGE_SIZE - page_offset; 226 page_remainder = PAGE_SIZE - page_offset;
238 if (page_remainder < (sizeof(struct qeth_hdr) + hdr_len)){ 227 if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){
239 /* no -> go to start of next page */ 228 /* no -> go to start of next page */
240 ctx->offset += page_remainder; 229 ctx->offset += page_remainder;
241 page = ctx->pages[ctx->offset >> PAGE_SHIFT]; 230 page = ctx->pages[ctx->offset >> PAGE_SHIFT];
@@ -281,7 +270,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
281 int left_in_frag; 270 int left_in_frag;
282 int copy_len; 271 int copy_len;
283 u8 *src; 272 u8 *src;
284 273
285 QETH_DBF_TEXT(trace, 5, "eddpcdtc"); 274 QETH_DBF_TEXT(trace, 5, "eddpcdtc");
286 if (skb_shinfo(eddp->skb)->nr_frags == 0) { 275 if (skb_shinfo(eddp->skb)->nr_frags == 0) {
287 memcpy(dst, eddp->skb->data + eddp->skb_offset, len); 276 memcpy(dst, eddp->skb->data + eddp->skb_offset, len);
@@ -292,7 +281,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
292 while (len > 0) { 281 while (len > 0) {
293 if (eddp->frag < 0) { 282 if (eddp->frag < 0) {
294 /* we're in skb->data */ 283 /* we're in skb->data */
295 left_in_frag = qeth_get_skb_data_len(eddp->skb) 284 left_in_frag = (eddp->skb->len - eddp->skb->data_len)
296 - eddp->skb_offset; 285 - eddp->skb_offset;
297 src = eddp->skb->data + eddp->skb_offset; 286 src = eddp->skb->data + eddp->skb_offset;
298 } else { 287 } else {
@@ -424,7 +413,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
424 struct tcphdr *tcph; 413 struct tcphdr *tcph;
425 int data_len; 414 int data_len;
426 u32 hcsum; 415 u32 hcsum;
427 416
428 QETH_DBF_TEXT(trace, 5, "eddpftcp"); 417 QETH_DBF_TEXT(trace, 5, "eddpftcp");
429 eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; 418 eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
430 tcph = eddp->skb->h.th; 419 tcph = eddp->skb->h.th;
@@ -464,7 +453,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
464 else 453 else
465 hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len); 454 hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
466 /* fill the next segment into the context */ 455 /* fill the next segment into the context */
467 qeth_eddp_create_segment_hdrs(ctx, eddp); 456 qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
468 qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum); 457 qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
469 if (eddp->skb_offset >= eddp->skb->len) 458 if (eddp->skb_offset >= eddp->skb->len)
470 break; 459 break;
@@ -474,13 +463,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
474 eddp->th.tcp.h.seq += data_len; 463 eddp->th.tcp.h.seq += data_len;
475 } 464 }
476} 465}
477 466
478static inline int 467static inline int
479qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, 468qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
480 struct sk_buff *skb, struct qeth_hdr *qhdr) 469 struct sk_buff *skb, struct qeth_hdr *qhdr)
481{ 470{
482 struct qeth_eddp_data *eddp = NULL; 471 struct qeth_eddp_data *eddp = NULL;
483 472
484 QETH_DBF_TEXT(trace, 5, "eddpficx"); 473 QETH_DBF_TEXT(trace, 5, "eddpficx");
485 /* create our segmentation headers and copy original headers */ 474 /* create our segmentation headers and copy original headers */
486 if (skb->protocol == ETH_P_IP) 475 if (skb->protocol == ETH_P_IP)
@@ -520,7 +509,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
520 int hdr_len) 509 int hdr_len)
521{ 510{
522 int skbs_per_page; 511 int skbs_per_page;
523 512
524 QETH_DBF_TEXT(trace, 5, "eddpcanp"); 513 QETH_DBF_TEXT(trace, 5, "eddpcanp");
525 /* can we put multiple skbs in one page? */ 514 /* can we put multiple skbs in one page? */
526 skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); 515 skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
@@ -600,7 +589,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
600 struct qeth_hdr *qhdr) 589 struct qeth_hdr *qhdr)
601{ 590{
602 struct qeth_eddp_context *ctx = NULL; 591 struct qeth_eddp_context *ctx = NULL;
603 592
604 QETH_DBF_TEXT(trace, 5, "creddpct"); 593 QETH_DBF_TEXT(trace, 5, "creddpct");
605 if (skb->protocol == ETH_P_IP) 594 if (skb->protocol == ETH_P_IP)
606 ctx = qeth_eddp_create_context_generic(card, skb, 595 ctx = qeth_eddp_create_context_generic(card, skb,
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 607b92542df6..208127a5033a 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.206 $) 3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * 6 *
@@ -12,7 +12,7 @@
12 * Frank Pavlic (pavlic@de.ibm.com) and 12 * Frank Pavlic (pavlic@de.ibm.com) and
13 * Thomas Spatzier <tspat@de.ibm.com> 13 * Thomas Spatzier <tspat@de.ibm.com>
14 * 14 *
15 * $Revision: 1.206 $ $Date: 2005/03/24 09:04:18 $ 15 * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $
16 * 16 *
17 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -80,7 +80,7 @@ qeth_eyecatcher(void)
80#include "qeth_eddp.h" 80#include "qeth_eddp.h"
81#include "qeth_tso.h" 81#include "qeth_tso.h"
82 82
83#define VERSION_QETH_C "$Revision: 1.206 $" 83#define VERSION_QETH_C "$Revision: 1.214 $"
84static const char *version = "qeth S/390 OSA-Express driver"; 84static const char *version = "qeth S/390 OSA-Express driver";
85 85
86/** 86/**
@@ -158,6 +158,9 @@ qeth_irq_tasklet(unsigned long);
158static int 158static int
159qeth_set_online(struct ccwgroup_device *); 159qeth_set_online(struct ccwgroup_device *);
160 160
161static int
162__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode);
163
161static struct qeth_ipaddr * 164static struct qeth_ipaddr *
162qeth_get_addr_buffer(enum qeth_prot_versions); 165qeth_get_addr_buffer(enum qeth_prot_versions);
163 166
@@ -510,10 +513,10 @@ qeth_irq_tasklet(unsigned long data)
510 wake_up(&card->wait_q); 513 wake_up(&card->wait_q);
511} 514}
512 515
513static int qeth_stop_card(struct qeth_card *); 516static int qeth_stop_card(struct qeth_card *, int);
514 517
515static int 518static int
516qeth_set_offline(struct ccwgroup_device *cgdev) 519__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
517{ 520{
518 struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; 521 struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
519 int rc = 0; 522 int rc = 0;
@@ -523,7 +526,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
523 QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); 526 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
524 527
525 recover_flag = card->state; 528 recover_flag = card->state;
526 if (qeth_stop_card(card) == -ERESTARTSYS){ 529 if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
527 PRINT_WARN("Stopping card %s interrupted by user!\n", 530 PRINT_WARN("Stopping card %s interrupted by user!\n",
528 CARD_BUS_ID(card)); 531 CARD_BUS_ID(card));
529 return -ERESTARTSYS; 532 return -ERESTARTSYS;
@@ -540,6 +543,12 @@ qeth_set_offline(struct ccwgroup_device *cgdev)
540} 543}
541 544
542static int 545static int
546qeth_set_offline(struct ccwgroup_device *cgdev)
547{
548 return __qeth_set_offline(cgdev, 0);
549}
550
551static int
543qeth_wait_for_threads(struct qeth_card *card, unsigned long threads); 552qeth_wait_for_threads(struct qeth_card *card, unsigned long threads);
544 553
545 554
@@ -953,8 +962,8 @@ qeth_recover(void *ptr)
953 PRINT_WARN("Recovery of device %s started ...\n", 962 PRINT_WARN("Recovery of device %s started ...\n",
954 CARD_BUS_ID(card)); 963 CARD_BUS_ID(card));
955 card->use_hard_stop = 1; 964 card->use_hard_stop = 1;
956 qeth_set_offline(card->gdev); 965 __qeth_set_offline(card->gdev,1);
957 rc = qeth_set_online(card->gdev); 966 rc = __qeth_set_online(card->gdev,1);
958 if (!rc) 967 if (!rc)
959 PRINT_INFO("Device %s successfully recovered!\n", 968 PRINT_INFO("Device %s successfully recovered!\n",
960 CARD_BUS_ID(card)); 969 CARD_BUS_ID(card));
@@ -2152,9 +2161,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
2152 if (!skb_len) 2161 if (!skb_len)
2153 return NULL; 2162 return NULL;
2154 if (card->options.fake_ll){ 2163 if (card->options.fake_ll){
2155 if (!(skb = qeth_get_skb(skb_len + QETH_FAKE_LL_LEN))) 2164 if(card->dev->type == ARPHRD_IEEE802_TR){
2156 goto no_mem; 2165 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR)))
2157 skb_pull(skb, QETH_FAKE_LL_LEN); 2166 goto no_mem;
2167 skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
2168 } else {
2169 if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH)))
2170 goto no_mem;
2171 skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
2172 }
2158 } else if (!(skb = qeth_get_skb(skb_len))) 2173 } else if (!(skb = qeth_get_skb(skb_len)))
2159 goto no_mem; 2174 goto no_mem;
2160 data_ptr = element->addr + offset; 2175 data_ptr = element->addr + offset;
@@ -2229,14 +2244,68 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
2229} 2244}
2230 2245
2231static inline void 2246static inline void
2232qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, 2247qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
2248 struct qeth_hdr *hdr)
2249{
2250 struct trh_hdr *fake_hdr;
2251 struct trllc *fake_llc;
2252 struct iphdr *ip_hdr;
2253
2254 QETH_DBF_TEXT(trace,5,"skbfktr");
2255 skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_TR;
2256 /* this is a fake ethernet header */
2257 fake_hdr = (struct trh_hdr *) skb->mac.raw;
2258
2259 /* the destination MAC address */
2260 switch (skb->pkt_type){
2261 case PACKET_MULTICAST:
2262 switch (skb->protocol){
2263#ifdef CONFIG_QETH_IPV6
2264 case __constant_htons(ETH_P_IPV6):
2265 ndisc_mc_map((struct in6_addr *)
2266 skb->data + QETH_FAKE_LL_V6_ADDR_POS,
2267 fake_hdr->daddr, card->dev, 0);
2268 break;
2269#endif /* CONFIG_QETH_IPV6 */
2270 case __constant_htons(ETH_P_IP):
2271 ip_hdr = (struct iphdr *)skb->data;
2272 ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr);
2273 break;
2274 default:
2275 memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
2276 }
2277 break;
2278 case PACKET_BROADCAST:
2279 memset(fake_hdr->daddr, 0xff, TR_ALEN);
2280 break;
2281 default:
2282 memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
2283 }
2284 /* the source MAC address */
2285 if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
2286 memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN);
2287 else
2288 memset(fake_hdr->saddr, 0, TR_ALEN);
2289 fake_hdr->rcf=0;
2290 fake_llc = (struct trllc*)&(fake_hdr->rcf);
2291 fake_llc->dsap = EXTENDED_SAP;
2292 fake_llc->ssap = EXTENDED_SAP;
2293 fake_llc->llc = UI_CMD;
2294 fake_llc->protid[0] = 0;
2295 fake_llc->protid[1] = 0;
2296 fake_llc->protid[2] = 0;
2297 fake_llc->ethertype = ETH_P_IP;
2298}
2299
2300static inline void
2301qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
2233 struct qeth_hdr *hdr) 2302 struct qeth_hdr *hdr)
2234{ 2303{
2235 struct ethhdr *fake_hdr; 2304 struct ethhdr *fake_hdr;
2236 struct iphdr *ip_hdr; 2305 struct iphdr *ip_hdr;
2237 2306
2238 QETH_DBF_TEXT(trace,5,"skbfake"); 2307 QETH_DBF_TEXT(trace,5,"skbfketh");
2239 skb->mac.raw = skb->data - QETH_FAKE_LL_LEN; 2308 skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_ETH;
2240 /* this is a fake ethernet header */ 2309 /* this is a fake ethernet header */
2241 fake_hdr = (struct ethhdr *) skb->mac.raw; 2310 fake_hdr = (struct ethhdr *) skb->mac.raw;
2242 2311
@@ -2253,10 +2322,7 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
2253#endif /* CONFIG_QETH_IPV6 */ 2322#endif /* CONFIG_QETH_IPV6 */
2254 case __constant_htons(ETH_P_IP): 2323 case __constant_htons(ETH_P_IP):
2255 ip_hdr = (struct iphdr *)skb->data; 2324 ip_hdr = (struct iphdr *)skb->data;
2256 if (card->dev->type == ARPHRD_IEEE802_TR) 2325 ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
2257 ip_tr_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
2258 else
2259 ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
2260 break; 2326 break;
2261 default: 2327 default:
2262 memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN); 2328 memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
@@ -2278,6 +2344,16 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
2278} 2344}
2279 2345
2280static inline void 2346static inline void
2347qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
2348 struct qeth_hdr *hdr)
2349{
2350 if (card->dev->type == ARPHRD_IEEE802_TR)
2351 qeth_rebuild_skb_fake_ll_tr(card, skb, hdr);
2352 else
2353 qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
2354}
2355
2356static inline void
2281qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb, 2357qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb,
2282 struct qeth_hdr *hdr) 2358 struct qeth_hdr *hdr)
2283{ 2359{
@@ -3440,16 +3516,25 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
3440 unsigned short type, void *daddr, void *saddr, 3516 unsigned short type, void *daddr, void *saddr,
3441 unsigned len) 3517 unsigned len)
3442{ 3518{
3443 struct ethhdr *hdr; 3519 if(dev->type == ARPHRD_IEEE802_TR){
3520 struct trh_hdr *hdr;
3521 hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR);
3522 memcpy(hdr->saddr, dev->dev_addr, TR_ALEN);
3523 memcpy(hdr->daddr, "FAKELL", TR_ALEN);
3524 return QETH_FAKE_LL_LEN_TR;
3525
3526 } else {
3527 struct ethhdr *hdr;
3528 hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH);
3529 memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
3530 memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
3531 if (type != ETH_P_802_3)
3532 hdr->h_proto = htons(type);
3533 else
3534 hdr->h_proto = htons(len);
3535 return QETH_FAKE_LL_LEN_ETH;
3444 3536
3445 hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN); 3537 }
3446 memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
3447 memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
3448 if (type != ETH_P_802_3)
3449 hdr->h_proto = htons(type);
3450 else
3451 hdr->h_proto = htons(len);
3452 return QETH_FAKE_LL_LEN;
3453} 3538}
3454 3539
3455static inline int 3540static inline int
@@ -3710,16 +3795,12 @@ static inline int
3710qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, 3795qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
3711 struct qeth_hdr **hdr, int ipv) 3796 struct qeth_hdr **hdr, int ipv)
3712{ 3797{
3713 int rc = 0;
3714#ifdef CONFIG_QETH_VLAN 3798#ifdef CONFIG_QETH_VLAN
3715 u16 *tag; 3799 u16 *tag;
3716#endif 3800#endif
3717 3801
3718 QETH_DBF_TEXT(trace, 6, "prepskb"); 3802 QETH_DBF_TEXT(trace, 6, "prepskb");
3719 3803
3720 rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
3721 if (rc)
3722 return rc;
3723#ifdef CONFIG_QETH_VLAN 3804#ifdef CONFIG_QETH_VLAN
3724 if (card->vlangrp && vlan_tx_tag_present(*skb) && 3805 if (card->vlangrp && vlan_tx_tag_present(*skb) &&
3725 ((ipv == 6) || card->options.layer2) ) { 3806 ((ipv == 6) || card->options.layer2) ) {
@@ -3882,9 +3963,15 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
3882 memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16); 3963 memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16);
3883 } 3964 }
3884 } else { /* passthrough */ 3965 } else { /* passthrough */
3885 if (!memcmp(skb->data + sizeof(struct qeth_hdr), 3966 if((skb->dev->type == ARPHRD_IEEE802_TR) &&
3967 !memcmp(skb->data + sizeof(struct qeth_hdr) +
3968 sizeof(__u16), skb->dev->broadcast, 6)) {
3969 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
3970 QETH_HDR_PASSTHRU;
3971 } else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
3886 skb->dev->broadcast, 6)) { /* broadcast? */ 3972 skb->dev->broadcast, 6)) { /* broadcast? */
3887 hdr->hdr.l3.flags = QETH_CAST_BROADCAST | QETH_HDR_PASSTHRU; 3973 hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
3974 QETH_HDR_PASSTHRU;
3888 } else { 3975 } else {
3889 hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ? 3976 hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ?
3890 QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU : 3977 QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU :
@@ -3894,67 +3981,29 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
3894} 3981}
3895 3982
3896static inline void 3983static inline void
3897__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
3898 int *next_element_to_fill)
3899{
3900 int length = skb->len;
3901 struct skb_frag_struct *frag;
3902 int fragno;
3903 unsigned long addr;
3904 int element;
3905 int first_lap = 1;
3906
3907 fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */
3908 element = *next_element_to_fill + fragno;
3909 while (length > 0) {
3910 if (fragno > 0) {
3911 frag = &skb_shinfo(skb)->frags[fragno - 1];
3912 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
3913 frag->page_offset;
3914 buffer->element[element].addr = (char *)addr;
3915 buffer->element[element].length = frag->size;
3916 length -= frag->size;
3917 if (first_lap)
3918 buffer->element[element].flags =
3919 SBAL_FLAGS_LAST_FRAG;
3920 else
3921 buffer->element[element].flags =
3922 SBAL_FLAGS_MIDDLE_FRAG;
3923 } else {
3924 buffer->element[element].addr = skb->data;
3925 buffer->element[element].length = length;
3926 length = 0;
3927 buffer->element[element].flags =
3928 SBAL_FLAGS_FIRST_FRAG;
3929 }
3930 element--;
3931 fragno--;
3932 first_lap = 0;
3933 }
3934 *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1;
3935}
3936
3937static inline void
3938__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, 3984__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
3939 int *next_element_to_fill) 3985 int is_tso, int *next_element_to_fill)
3940{ 3986{
3941 int length = skb->len; 3987 int length = skb->len;
3942 int length_here; 3988 int length_here;
3943 int element; 3989 int element;
3944 char *data; 3990 char *data;
3945 int first_lap = 1; 3991 int first_lap ;
3946 3992
3947 element = *next_element_to_fill; 3993 element = *next_element_to_fill;
3948 data = skb->data; 3994 data = skb->data;
3995 first_lap = (is_tso == 0 ? 1 : 0);
3996
3949 while (length > 0) { 3997 while (length > 0) {
3950 /* length_here is the remaining amount of data in this page */ 3998 /* length_here is the remaining amount of data in this page */
3951 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); 3999 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
3952 if (length < length_here) 4000 if (length < length_here)
3953 length_here = length; 4001 length_here = length;
4002
3954 buffer->element[element].addr = data; 4003 buffer->element[element].addr = data;
3955 buffer->element[element].length = length_here; 4004 buffer->element[element].length = length_here;
3956 length -= length_here; 4005 length -= length_here;
3957 if (!length){ 4006 if (!length) {
3958 if (first_lap) 4007 if (first_lap)
3959 buffer->element[element].flags = 0; 4008 buffer->element[element].flags = 0;
3960 else 4009 else
@@ -3981,17 +4030,35 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue,
3981 struct sk_buff *skb) 4030 struct sk_buff *skb)
3982{ 4031{
3983 struct qdio_buffer *buffer; 4032 struct qdio_buffer *buffer;
3984 int flush_cnt = 0; 4033 struct qeth_hdr_tso *hdr;
4034 int flush_cnt = 0, hdr_len, large_send = 0;
3985 4035
3986 QETH_DBF_TEXT(trace, 6, "qdfillbf"); 4036 QETH_DBF_TEXT(trace, 6, "qdfillbf");
4037
3987 buffer = buf->buffer; 4038 buffer = buf->buffer;
3988 atomic_inc(&skb->users); 4039 atomic_inc(&skb->users);
3989 skb_queue_tail(&buf->skb_list, skb); 4040 skb_queue_tail(&buf->skb_list, skb);
4041
4042 hdr = (struct qeth_hdr_tso *) skb->data;
4043 /*check first on TSO ....*/
4044 if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) {
4045 int element = buf->next_element_to_fill;
4046
4047 hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
4048 /*fill first buffer entry only with header information */
4049 buffer->element[element].addr = skb->data;
4050 buffer->element[element].length = hdr_len;
4051 buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
4052 buf->next_element_to_fill++;
4053 skb->data += hdr_len;
4054 skb->len -= hdr_len;
4055 large_send = 1;
4056 }
3990 if (skb_shinfo(skb)->nr_frags == 0) 4057 if (skb_shinfo(skb)->nr_frags == 0)
3991 __qeth_fill_buffer(skb, buffer, 4058 __qeth_fill_buffer(skb, buffer, large_send,
3992 (int *)&buf->next_element_to_fill); 4059 (int *)&buf->next_element_to_fill);
3993 else 4060 else
3994 __qeth_fill_buffer_frag(skb, buffer, 4061 __qeth_fill_buffer_frag(skb, buffer, large_send,
3995 (int *)&buf->next_element_to_fill); 4062 (int *)&buf->next_element_to_fill);
3996 4063
3997 if (!queue->do_pack) { 4064 if (!queue->do_pack) {
@@ -4184,6 +4251,25 @@ out:
4184} 4251}
4185 4252
4186static inline int 4253static inline int
4254qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
4255{
4256 int elements_needed = 0;
4257
4258 if (skb_shinfo(skb)->nr_frags > 0) {
4259 elements_needed = (skb_shinfo(skb)->nr_frags + 1);
4260 }
4261 if (elements_needed == 0 )
4262 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
4263 + skb->len) >> PAGE_SHIFT);
4264 if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
4265 PRINT_ERR("qeth_do_send_packet: invalid size of "
4266 "IP packet. Discarded.");
4267 return 0;
4268 }
4269 return elements_needed;
4270}
4271
4272static inline int
4187qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) 4273qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4188{ 4274{
4189 int ipv = 0; 4275 int ipv = 0;
@@ -4205,7 +4291,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4205 dev_kfree_skb_irq(skb); 4291 dev_kfree_skb_irq(skb);
4206 return 0; 4292 return 0;
4207 } 4293 }
4208 skb_pull(skb, QETH_FAKE_LL_LEN); 4294 if(card->dev->type == ARPHRD_IEEE802_TR){
4295 skb_pull(skb, QETH_FAKE_LL_LEN_TR);
4296 } else {
4297 skb_pull(skb, QETH_FAKE_LL_LEN_ETH);
4298 }
4209 } 4299 }
4210 } 4300 }
4211 cast_type = qeth_get_cast_type(card, skb); 4301 cast_type = qeth_get_cast_type(card, skb);
@@ -4221,19 +4311,25 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4221 if (skb_shinfo(skb)->tso_size) 4311 if (skb_shinfo(skb)->tso_size)
4222 large_send = card->options.large_send; 4312 large_send = card->options.large_send;
4223 4313
4224 if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))){
4225 QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
4226 return rc;
4227 }
4228 /*are we able to do TSO ? If so ,prepare and send it from here */ 4314 /*are we able to do TSO ? If so ,prepare and send it from here */
4229 if ((large_send == QETH_LARGE_SEND_TSO) && 4315 if ((large_send == QETH_LARGE_SEND_TSO) &&
4230 (cast_type == RTN_UNSPEC)) { 4316 (cast_type == RTN_UNSPEC)) {
4231 rc = qeth_tso_send_packet(card, skb, queue, 4317 rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type);
4232 ipv, cast_type); 4318 if (rc) {
4233 goto do_statistics; 4319 card->stats.tx_dropped++;
4320 card->stats.tx_errors++;
4321 dev_kfree_skb_any(skb);
4322 return NETDEV_TX_OK;
4323 }
4324 elements_needed++;
4325 } else {
4326 if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) {
4327 QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
4328 return rc;
4329 }
4330 qeth_fill_header(card, hdr, skb, ipv, cast_type);
4234 } 4331 }
4235 4332
4236 qeth_fill_header(card, hdr, skb, ipv, cast_type);
4237 if (large_send == QETH_LARGE_SEND_EDDP) { 4333 if (large_send == QETH_LARGE_SEND_EDDP) {
4238 ctx = qeth_eddp_create_context(card, skb, hdr); 4334 ctx = qeth_eddp_create_context(card, skb, hdr);
4239 if (ctx == NULL) { 4335 if (ctx == NULL) {
@@ -4241,7 +4337,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4241 return -EINVAL; 4337 return -EINVAL;
4242 } 4338 }
4243 } else { 4339 } else {
4244 elements_needed = qeth_get_elements_no(card,(void*) hdr, skb); 4340 elements_needed += qeth_get_elements_no(card,(void*) hdr, skb);
4245 if (!elements_needed) 4341 if (!elements_needed)
4246 return -EINVAL; 4342 return -EINVAL;
4247 } 4343 }
@@ -4252,12 +4348,12 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4252 else 4348 else
4253 rc = qeth_do_send_packet_fast(card, queue, skb, hdr, 4349 rc = qeth_do_send_packet_fast(card, queue, skb, hdr,
4254 elements_needed, ctx); 4350 elements_needed, ctx);
4255do_statistics:
4256 if (!rc){ 4351 if (!rc){
4257 card->stats.tx_packets++; 4352 card->stats.tx_packets++;
4258 card->stats.tx_bytes += skb->len; 4353 card->stats.tx_bytes += skb->len;
4259#ifdef CONFIG_QETH_PERF_STATS 4354#ifdef CONFIG_QETH_PERF_STATS
4260 if (skb_shinfo(skb)->tso_size) { 4355 if (skb_shinfo(skb)->tso_size &&
4356 !(large_send == QETH_LARGE_SEND_NO)) {
4261 card->perf_stats.large_send_bytes += skb->len; 4357 card->perf_stats.large_send_bytes += skb->len;
4262 card->perf_stats.large_send_cnt++; 4358 card->perf_stats.large_send_cnt++;
4263 } 4359 }
@@ -7154,7 +7250,7 @@ qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
7154} 7250}
7155 7251
7156static int 7252static int
7157qeth_stop_card(struct qeth_card *card) 7253qeth_stop_card(struct qeth_card *card, int recovery_mode)
7158{ 7254{
7159 int rc = 0; 7255 int rc = 0;
7160 7256
@@ -7167,9 +7263,13 @@ qeth_stop_card(struct qeth_card *card)
7167 if (card->read.state == CH_STATE_UP && 7263 if (card->read.state == CH_STATE_UP &&
7168 card->write.state == CH_STATE_UP && 7264 card->write.state == CH_STATE_UP &&
7169 (card->state == CARD_STATE_UP)) { 7265 (card->state == CARD_STATE_UP)) {
7170 rtnl_lock(); 7266 if(recovery_mode) {
7171 dev_close(card->dev); 7267 qeth_stop(card->dev);
7172 rtnl_unlock(); 7268 } else {
7269 rtnl_lock();
7270 dev_close(card->dev);
7271 rtnl_unlock();
7272 }
7173 if (!card->use_hard_stop) { 7273 if (!card->use_hard_stop) {
7174 __u8 *mac = &card->dev->dev_addr[0]; 7274 __u8 *mac = &card->dev->dev_addr[0];
7175 rc = qeth_layer2_send_delmac(card, mac); 7275 rc = qeth_layer2_send_delmac(card, mac);
@@ -7341,13 +7441,17 @@ qeth_register_netdev(struct qeth_card *card)
7341} 7441}
7342 7442
7343static void 7443static void
7344qeth_start_again(struct qeth_card *card) 7444qeth_start_again(struct qeth_card *card, int recovery_mode)
7345{ 7445{
7346 QETH_DBF_TEXT(setup ,2, "startag"); 7446 QETH_DBF_TEXT(setup ,2, "startag");
7347 7447
7348 rtnl_lock(); 7448 if(recovery_mode) {
7349 dev_open(card->dev); 7449 qeth_open(card->dev);
7350 rtnl_unlock(); 7450 } else {
7451 rtnl_lock();
7452 dev_open(card->dev);
7453 rtnl_unlock();
7454 }
7351 /* this also sets saved unicast addresses */ 7455 /* this also sets saved unicast addresses */
7352 qeth_set_multicast_list(card->dev); 7456 qeth_set_multicast_list(card->dev);
7353} 7457}
@@ -7404,7 +7508,7 @@ static void qeth_make_parameters_consistent(struct qeth_card *card)
7404 7508
7405 7509
7406static int 7510static int
7407qeth_set_online(struct ccwgroup_device *gdev) 7511__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
7408{ 7512{
7409 struct qeth_card *card = gdev->dev.driver_data; 7513 struct qeth_card *card = gdev->dev.driver_data;
7410 int rc = 0; 7514 int rc = 0;
@@ -7464,12 +7568,12 @@ qeth_set_online(struct ccwgroup_device *gdev)
7464 * we can also use this state for recovery purposes*/ 7568 * we can also use this state for recovery purposes*/
7465 qeth_set_allowed_threads(card, 0xffffffff, 0); 7569 qeth_set_allowed_threads(card, 0xffffffff, 0);
7466 if (recover_flag == CARD_STATE_RECOVER) 7570 if (recover_flag == CARD_STATE_RECOVER)
7467 qeth_start_again(card); 7571 qeth_start_again(card, recovery_mode);
7468 qeth_notify_processes(); 7572 qeth_notify_processes();
7469 return 0; 7573 return 0;
7470out_remove: 7574out_remove:
7471 card->use_hard_stop = 1; 7575 card->use_hard_stop = 1;
7472 qeth_stop_card(card); 7576 qeth_stop_card(card, 0);
7473 ccw_device_set_offline(CARD_DDEV(card)); 7577 ccw_device_set_offline(CARD_DDEV(card));
7474 ccw_device_set_offline(CARD_WDEV(card)); 7578 ccw_device_set_offline(CARD_WDEV(card));
7475 ccw_device_set_offline(CARD_RDEV(card)); 7579 ccw_device_set_offline(CARD_RDEV(card));
@@ -7480,6 +7584,12 @@ out_remove:
7480 return -ENODEV; 7584 return -ENODEV;
7481} 7585}
7482 7586
7587static int
7588qeth_set_online(struct ccwgroup_device *gdev)
7589{
7590 return __qeth_set_online(gdev, 0);
7591}
7592
7483static struct ccw_device_id qeth_ids[] = { 7593static struct ccw_device_id qeth_ids[] = {
7484 {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE}, 7594 {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE},
7485 {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD}, 7595 {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD},
diff --git a/drivers/s390/net/qeth_tso.c b/drivers/s390/net/qeth_tso.c
deleted file mode 100644
index c91976274e7b..000000000000
--- a/drivers/s390/net/qeth_tso.c
+++ /dev/null
@@ -1,285 +0,0 @@
1/*
2 * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.6 $)
3 *
4 * Header file for qeth TCP Segmentation Offload support.
5 *
6 * Copyright 2004 IBM Corporation
7 *
8 * Author(s): Frank Pavlic <pavlic@de.ibm.com>
9 *
10 * $Revision: 1.6 $ $Date: 2005/03/24 09:04:18 $
11 *
12 */
13
14#include <linux/skbuff.h>
15#include <linux/tcp.h>
16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <net/ip6_checksum.h>
19#include "qeth.h"
20#include "qeth_mpc.h"
21#include "qeth_tso.h"
22
23/**
24 * skb already partially prepared
25 * classic qdio header in skb->data
26 * */
27static inline struct qeth_hdr_tso *
28qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
29{
30 int rc = 0;
31
32 QETH_DBF_TEXT(trace, 5, "tsoprsk");
33 rc = qeth_realloc_headroom(card, skb,sizeof(struct qeth_hdr_ext_tso));
34 if (rc)
35 return NULL;
36
37 return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_ext_tso));
38}
39
40/**
41 * fill header for a TSO packet
42 */
43static inline void
44qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
45{
46 struct qeth_hdr_tso *hdr;
47 struct tcphdr *tcph;
48 struct iphdr *iph;
49
50 QETH_DBF_TEXT(trace, 5, "tsofhdr");
51
52 hdr = (struct qeth_hdr_tso *) skb->data;
53 iph = skb->nh.iph;
54 tcph = skb->h.th;
55 /*fix header to TSO values ...*/
56 hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
57 /*set values which are fix for the first approach ...*/
58 hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
59 hdr->ext.imb_hdr_no = 1;
60 hdr->ext.hdr_type = 1;
61 hdr->ext.hdr_version = 1;
62 hdr->ext.hdr_len = 28;
63 /*insert non-fix values */
64 hdr->ext.mss = skb_shinfo(skb)->tso_size;
65 hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
66 hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
67 sizeof(struct qeth_hdr_tso));
68}
69
70/**
71 * change some header values as requested by hardware
72 */
73static inline void
74qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
75{
76 struct iphdr *iph;
77 struct ipv6hdr *ip6h;
78 struct tcphdr *tcph;
79
80 iph = skb->nh.iph;
81 ip6h = skb->nh.ipv6h;
82 tcph = skb->h.th;
83
84 tcph->check = 0;
85 if (skb->protocol == ETH_P_IPV6) {
86 ip6h->payload_len = 0;
87 tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
88 0, IPPROTO_TCP, 0);
89 return;
90 }
91 /*OSA want us to set these values ...*/
92 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
93 0, IPPROTO_TCP, 0);
94 iph->tot_len = 0;
95 iph->check = 0;
96}
97
98static inline struct qeth_hdr_tso *
99qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
100 int ipv, int cast_type)
101{
102 struct qeth_hdr_tso *hdr;
103 int rc = 0;
104
105 QETH_DBF_TEXT(trace, 5, "tsoprep");
106
107 /*get headroom for tso qdio header */
108 hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
109 if (hdr == NULL) {
110 QETH_DBF_TEXT_(trace, 4, "2err%d", rc);
111 return NULL;
112 }
113 memset(hdr, 0, sizeof(struct qeth_hdr_tso));
114 /*fill first 32 bytes of qdio header as used
115 *FIXME: TSO has two struct members
116 * with different names but same size
117 * */
118 qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
119 qeth_tso_fill_header(card, skb);
120 qeth_tso_set_tcpip_header(card, skb);
121 return hdr;
122}
123
124static inline int
125qeth_tso_get_queue_buffer(struct qeth_qdio_out_q *queue)
126{
127 struct qeth_qdio_out_buffer *buffer;
128 int flush_cnt = 0;
129
130 QETH_DBF_TEXT(trace, 5, "tsobuf");
131
132 /* force to non-packing*/
133 if (queue->do_pack)
134 queue->do_pack = 0;
135 buffer = &queue->bufs[queue->next_buf_to_fill];
136 /* get a new buffer if current is already in use*/
137 if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
138 (buffer->next_element_to_fill > 0)) {
139 atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
140 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
141 QDIO_MAX_BUFFERS_PER_Q;
142 flush_cnt++;
143 }
144 return flush_cnt;
145}
146
147static inline void
148__qeth_tso_fill_buffer_frag(struct qeth_qdio_out_buffer *buf,
149 struct sk_buff *skb)
150{
151 struct skb_frag_struct *frag;
152 struct qdio_buffer *buffer;
153 int fragno, cnt, element;
154 unsigned long addr;
155
156 QETH_DBF_TEXT(trace, 6, "tsfilfrg");
157
158 /*initialize variables ...*/
159 fragno = skb_shinfo(skb)->nr_frags;
160 buffer = buf->buffer;
161 element = buf->next_element_to_fill;
162 /*fill buffer elements .....*/
163 for (cnt = 0; cnt < fragno; cnt++) {
164 frag = &skb_shinfo(skb)->frags[cnt];
165 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
166 frag->page_offset;
167 buffer->element[element].addr = (char *)addr;
168 buffer->element[element].length = frag->size;
169 if (cnt < (fragno - 1))
170 buffer->element[element].flags =
171 SBAL_FLAGS_MIDDLE_FRAG;
172 else
173 buffer->element[element].flags =
174 SBAL_FLAGS_LAST_FRAG;
175 element++;
176 }
177 buf->next_element_to_fill = element;
178}
179
180static inline int
181qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf,
182 struct sk_buff *skb)
183{
184 int length, length_here, element;
185 int hdr_len;
186 struct qdio_buffer *buffer;
187 struct qeth_hdr_tso *hdr;
188 char *data;
189
190 QETH_DBF_TEXT(trace, 3, "tsfilbuf");
191
192 /*increment user count and queue skb ...*/
193 atomic_inc(&skb->users);
194 skb_queue_tail(&buf->skb_list, skb);
195
196 /*initialize all variables...*/
197 buffer = buf->buffer;
198 hdr = (struct qeth_hdr_tso *)skb->data;
199 hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
200 data = skb->data + hdr_len;
201 length = skb->len - hdr_len;
202 element = buf->next_element_to_fill;
203 /*fill first buffer entry only with header information */
204 buffer->element[element].addr = skb->data;
205 buffer->element[element].length = hdr_len;
206 buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
207 buf->next_element_to_fill++;
208
209 if (skb_shinfo(skb)->nr_frags > 0) {
210 __qeth_tso_fill_buffer_frag(buf, skb);
211 goto out;
212 }
213
214 /*start filling buffer entries ...*/
215 element++;
216 while (length > 0) {
217 /* length_here is the remaining amount of data in this page */
218 length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
219 if (length < length_here)
220 length_here = length;
221 buffer->element[element].addr = data;
222 buffer->element[element].length = length_here;
223 length -= length_here;
224 if (!length)
225 buffer->element[element].flags =
226 SBAL_FLAGS_LAST_FRAG;
227 else
228 buffer->element[element].flags =
229 SBAL_FLAGS_MIDDLE_FRAG;
230 data += length_here;
231 element++;
232 }
233 /*set the buffer to primed ...*/
234 buf->next_element_to_fill = element;
235out:
236 atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
237 return 1;
238}
239
240int
241qeth_tso_send_packet(struct qeth_card *card, struct sk_buff *skb,
242 struct qeth_qdio_out_q *queue, int ipv, int cast_type)
243{
244 int flush_cnt = 0;
245 struct qeth_hdr_tso *hdr;
246 struct qeth_qdio_out_buffer *buffer;
247 int start_index;
248
249 QETH_DBF_TEXT(trace, 3, "tsosend");
250
251 if (!(hdr = qeth_tso_prepare_packet(card, skb, ipv, cast_type)))
252 return -ENOMEM;
253 /*check if skb fits in one SBAL ...*/
254 if (!(qeth_get_elements_no(card, (void*)hdr, skb)))
255 return -EINVAL;
256 /*lock queue, force switching to non-packing and send it ...*/
257 while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED,
258 QETH_OUT_Q_LOCKED,
259 &queue->state));
260 start_index = queue->next_buf_to_fill;
261 buffer = &queue->bufs[queue->next_buf_to_fill];
262 /*check if card is too busy ...*/
263 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
264 card->stats.tx_dropped++;
265 goto out;
266 }
267 /*let's force to non-packing and get a new SBAL*/
268 flush_cnt += qeth_tso_get_queue_buffer(queue);
269 buffer = &queue->bufs[queue->next_buf_to_fill];
270 if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
271 card->stats.tx_dropped++;
272 goto out;
273 }
274 flush_cnt += qeth_tso_fill_buffer(buffer, skb);
275 queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
276 QDIO_MAX_BUFFERS_PER_Q;
277out:
278 atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
279 if (flush_cnt)
280 qeth_flush_buffers(queue, 0, start_index, flush_cnt);
281 /*do some statistics */
282 card->stats.tx_packets++;
283 card->stats.tx_bytes += skb->len;
284 return 0;
285}
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 83504dee3f57..ad33e6f466f1 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.4 $) 2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $)
3 * 3 *
4 * Header file for qeth TCP Segmentation Offload support. 4 * Header file for qeth TCP Segmentation Offload support.
5 * 5 *
@@ -7,52 +7,148 @@
7 * 7 *
8 * Author(s): Frank Pavlic <pavlic@de.ibm.com> 8 * Author(s): Frank Pavlic <pavlic@de.ibm.com>
9 * 9 *
10 * $Revision: 1.4 $ $Date: 2005/03/24 09:04:18 $ 10 * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $
11 * 11 *
12 */ 12 */
13#ifndef __QETH_TSO_H__ 13#ifndef __QETH_TSO_H__
14#define __QETH_TSO_H__ 14#define __QETH_TSO_H__
15 15
16#include <linux/skbuff.h>
17#include <linux/tcp.h>
18#include <linux/ip.h>
19#include <linux/ipv6.h>
20#include <net/ip6_checksum.h>
21#include "qeth.h"
22#include "qeth_mpc.h"
16 23
17extern int
18qeth_tso_send_packet(struct qeth_card *, struct sk_buff *,
19 struct qeth_qdio_out_q *, int , int);
20 24
21struct qeth_hdr_ext_tso { 25static inline struct qeth_hdr_tso *
22 __u16 hdr_tot_len; 26qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
23 __u8 imb_hdr_no; 27{
24 __u8 reserved; 28 QETH_DBF_TEXT(trace, 5, "tsoprsk");
25 __u8 hdr_type; 29 return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso));
26 __u8 hdr_version; 30}
27 __u16 hdr_len; 31
28 __u32 payload_len; 32/**
29 __u16 mss; 33 * fill header for a TSO packet
30 __u16 dg_hdr_len; 34 */
31 __u8 padding[16]; 35static inline void
32} __attribute__ ((packed)); 36qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
37{
38 struct qeth_hdr_tso *hdr;
39 struct tcphdr *tcph;
40 struct iphdr *iph;
41
42 QETH_DBF_TEXT(trace, 5, "tsofhdr");
43
44 hdr = (struct qeth_hdr_tso *) skb->data;
45 iph = skb->nh.iph;
46 tcph = skb->h.th;
47 /*fix header to TSO values ...*/
48 hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
49 /*set values which are fix for the first approach ...*/
50 hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
51 hdr->ext.imb_hdr_no = 1;
52 hdr->ext.hdr_type = 1;
53 hdr->ext.hdr_version = 1;
54 hdr->ext.hdr_len = 28;
55 /*insert non-fix values */
56 hdr->ext.mss = skb_shinfo(skb)->tso_size;
57 hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
58 hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
59 sizeof(struct qeth_hdr_tso));
60}
61
62/**
63 * change some header values as requested by hardware
64 */
65static inline void
66qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
67{
68 struct iphdr *iph;
69 struct ipv6hdr *ip6h;
70 struct tcphdr *tcph;
33 71
34struct qeth_hdr_tso { 72 iph = skb->nh.iph;
35 struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ 73 ip6h = skb->nh.ipv6h;
36 struct qeth_hdr_ext_tso ext; 74 tcph = skb->h.th;
37} __attribute__ ((packed));
38 75
39/*some helper functions*/ 76 tcph->check = 0;
77 if (skb->protocol == ETH_P_IPV6) {
78 ip6h->payload_len = 0;
79 tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
80 0, IPPROTO_TCP, 0);
81 return;
82 }
83 /*OSA want us to set these values ...*/
84 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
85 0, IPPROTO_TCP, 0);
86 iph->tot_len = 0;
87 iph->check = 0;
88}
40 89
41static inline int 90static inline int
42qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) 91qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
92 int ipv, int cast_type)
93{
94 struct qeth_hdr_tso *hdr;
95
96 QETH_DBF_TEXT(trace, 5, "tsoprep");
97
98 hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
99 if (hdr == NULL) {
100 QETH_DBF_TEXT(trace, 4, "tsoperr");
101 return -ENOMEM;
102 }
103 memset(hdr, 0, sizeof(struct qeth_hdr_tso));
104 /*fill first 32 bytes of qdio header as used
105 *FIXME: TSO has two struct members
106 * with different names but same size
107 * */
108 qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
109 qeth_tso_fill_header(card, skb);
110 qeth_tso_set_tcpip_header(card, skb);
111 return 0;
112}
113
114static inline void
115__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
116 int is_tso, int *next_element_to_fill)
43{ 117{
44 int elements_needed = 0; 118 struct skb_frag_struct *frag;
45 119 int fragno;
46 if (skb_shinfo(skb)->nr_frags > 0) 120 unsigned long addr;
47 elements_needed = (skb_shinfo(skb)->nr_frags + 1); 121 int element, cnt, dlen;
48 if (elements_needed == 0 ) 122
49 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) 123 fragno = skb_shinfo(skb)->nr_frags;
50 + skb->len) >> PAGE_SHIFT); 124 element = *next_element_to_fill;
51 if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ 125 dlen = 0;
52 PRINT_ERR("qeth_do_send_packet: invalid size of " 126
53 "IP packet. Discarded."); 127 if (is_tso)
54 return 0; 128 buffer->element[element].flags =
129 SBAL_FLAGS_MIDDLE_FRAG;
130 else
131 buffer->element[element].flags =
132 SBAL_FLAGS_FIRST_FRAG;
133 if ( (dlen = (skb->len - skb->data_len)) ) {
134 buffer->element[element].addr = skb->data;
135 buffer->element[element].length = dlen;
136 element++;
137 }
138 for (cnt = 0; cnt < fragno; cnt++) {
139 frag = &skb_shinfo(skb)->frags[cnt];
140 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
141 frag->page_offset;
142 buffer->element[element].addr = (char *)addr;
143 buffer->element[element].length = frag->size;
144 if (cnt < (fragno - 1))
145 buffer->element[element].flags =
146 SBAL_FLAGS_MIDDLE_FRAG;
147 else
148 buffer->element[element].flags =
149 SBAL_FLAGS_LAST_FRAG;
150 element++;
55 } 151 }
56 return elements_needed; 152 *next_element_to_fill = element;
57} 153}
58#endif /* __QETH_TSO_H__ */ 154#endif /* __QETH_TSO_H__ */