aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-23 14:47:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-23 14:47:02 -0400
commit5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch)
tree7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/s390
parent02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff)
parentec37a48d1d16c30b655ac5280209edf52a6775d4 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits) bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL. vlan: Calling vlan_hwaccel_do_receive() is always valid. tproxy: use the interface primary IP address as a default value for --on-ip tproxy: added IPv6 support to the socket match cxgb3: function namespace cleanup tproxy: added IPv6 support to the TPROXY target tproxy: added IPv6 socket lookup function to nf_tproxy_core be2net: Changes to use only priority codes allowed by f/w tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled tproxy: added tproxy sockopt interface in the IPV6 layer tproxy: added udp6_lib_lookup function tproxy: added const specifiers to udp lookup functions tproxy: split off ipv6 defragmentation to a separate module l2tp: small cleanup nf_nat: restrict ICMP translation for embedded header can: mcp251x: fix generation of error frames can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set can-raw: add msg_flags to distinguish local traffic 9p: client code cleanup rds: make local functions/variables static ... Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio.h29
-rw-r--r--drivers/s390/cio/qdio_debug.c33
-rw-r--r--drivers/s390/cio/qdio_main.c138
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c66
-rw-r--r--drivers/s390/net/Kconfig2
-rw-r--r--drivers/s390/net/ctcm_mpc.c2
-rw-r--r--drivers/s390/net/qeth_core.h17
-rw-r--r--drivers/s390/net/qeth_core_main.c26
-rw-r--r--drivers/s390/net/qeth_l2_main.c175
-rw-r--r--drivers/s390/net/qeth_l3_main.c218
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c6
12 files changed, 496 insertions, 217 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index f0037eefd44..0f4ef8769a3 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -208,6 +208,7 @@ struct qdio_dev_perf_stat {
208 unsigned int eqbs_partial; 208 unsigned int eqbs_partial;
209 unsigned int sqbs; 209 unsigned int sqbs;
210 unsigned int sqbs_partial; 210 unsigned int sqbs_partial;
211 unsigned int int_discarded;
211} ____cacheline_aligned; 212} ____cacheline_aligned;
212 213
213struct qdio_queue_perf_stat { 214struct qdio_queue_perf_stat {
@@ -222,6 +223,10 @@ struct qdio_queue_perf_stat {
222 unsigned int nr_sbal_total; 223 unsigned int nr_sbal_total;
223}; 224};
224 225
226enum qdio_queue_irq_states {
227 QDIO_QUEUE_IRQS_DISABLED,
228};
229
225struct qdio_input_q { 230struct qdio_input_q {
226 /* input buffer acknowledgement flag */ 231 /* input buffer acknowledgement flag */
227 int polling; 232 int polling;
@@ -231,6 +236,10 @@ struct qdio_input_q {
231 int ack_count; 236 int ack_count;
232 /* last time of noticing incoming data */ 237 /* last time of noticing incoming data */
233 u64 timestamp; 238 u64 timestamp;
239 /* upper-layer polling flag */
240 unsigned long queue_irq_state;
241 /* callback to start upper-layer polling */
242 void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
234}; 243};
235 244
236struct qdio_output_q { 245struct qdio_output_q {
@@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q)
399#define sub_buf(bufnr, dec) \ 408#define sub_buf(bufnr, dec) \
400 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK) 409 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
401 410
411#define queue_irqs_enabled(q) \
412 (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0)
413#define queue_irqs_disabled(q) \
414 (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0)
415
416#define TIQDIO_SHARED_IND 63
417
418/* device state change indicators */
419struct indicator_t {
420 u32 ind; /* u32 because of compare-and-swap performance */
421 atomic_t count; /* use count, 0 or 1 for non-shared indicators */
422};
423
424extern struct indicator_t *q_indicators;
425
426static inline int shared_ind(struct qdio_irq *irq_ptr)
427{
428 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
429}
430
402/* prototypes for thin interrupt */ 431/* prototypes for thin interrupt */
403void qdio_setup_thinint(struct qdio_irq *irq_ptr); 432void qdio_setup_thinint(struct qdio_irq *irq_ptr);
404int qdio_establish_thinint(struct qdio_irq *irq_ptr); 433int qdio_establish_thinint(struct qdio_irq *irq_ptr);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 6ce83f56d53..28868e7471a 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -56,9 +56,16 @@ static int qstat_show(struct seq_file *m, void *v)
56 56
57 seq_printf(m, "DSCI: %d nr_used: %d\n", 57 seq_printf(m, "DSCI: %d nr_used: %d\n",
58 *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); 58 *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
59 seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); 59 seq_printf(m, "ftc: %d last_move: %d\n",
60 seq_printf(m, "polling: %d ack start: %d ack count: %d\n", 60 q->first_to_check, q->last_move);
61 q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); 61 if (q->is_input_q) {
62 seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
63 q->u.in.polling, q->u.in.ack_start,
64 q->u.in.ack_count);
65 seq_printf(m, "IRQs disabled: %u\n",
66 test_bit(QDIO_QUEUE_IRQS_DISABLED,
67 &q->u.in.queue_irq_state));
68 }
62 seq_printf(m, "SBAL states:\n"); 69 seq_printf(m, "SBAL states:\n");
63 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); 70 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
64 71
@@ -113,22 +120,6 @@ static int qstat_show(struct seq_file *m, void *v)
113 return 0; 120 return 0;
114} 121}
115 122
116static ssize_t qstat_seq_write(struct file *file, const char __user *buf,
117 size_t count, loff_t *off)
118{
119 struct seq_file *seq = file->private_data;
120 struct qdio_q *q = seq->private;
121
122 if (!q)
123 return 0;
124 if (q->is_input_q)
125 xchg(q->irq_ptr->dsci, 1);
126 local_bh_disable();
127 tasklet_schedule(&q->tasklet);
128 local_bh_enable();
129 return count;
130}
131
132static int qstat_seq_open(struct inode *inode, struct file *filp) 123static int qstat_seq_open(struct inode *inode, struct file *filp)
133{ 124{
134 return single_open(filp, qstat_show, 125 return single_open(filp, qstat_show,
@@ -139,7 +130,6 @@ static const struct file_operations debugfs_fops = {
139 .owner = THIS_MODULE, 130 .owner = THIS_MODULE,
140 .open = qstat_seq_open, 131 .open = qstat_seq_open,
141 .read = seq_read, 132 .read = seq_read,
142 .write = qstat_seq_write,
143 .llseek = seq_lseek, 133 .llseek = seq_lseek,
144 .release = single_release, 134 .release = single_release,
145}; 135};
@@ -166,7 +156,8 @@ static char *qperf_names[] = {
166 "QEBSM eqbs", 156 "QEBSM eqbs",
167 "QEBSM eqbs partial", 157 "QEBSM eqbs partial",
168 "QEBSM sqbs", 158 "QEBSM sqbs",
169 "QEBSM sqbs partial" 159 "QEBSM sqbs partial",
160 "Discarded interrupts"
170}; 161};
171 162
172static int qperf_show(struct seq_file *m, void *v) 163static int qperf_show(struct seq_file *m, void *v)
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 00520f9a7a8..5fcfa7f9e9e 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -884,8 +884,19 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
884 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 884 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
885 return; 885 return;
886 886
887 for_each_input_queue(irq_ptr, q, i) 887 for_each_input_queue(irq_ptr, q, i) {
888 tasklet_schedule(&q->tasklet); 888 if (q->u.in.queue_start_poll) {
889 /* skip if polling is enabled or already in work */
890 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
891 &q->u.in.queue_irq_state)) {
892 qperf_inc(q, int_discarded);
893 continue;
894 }
895 q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
896 q->irq_ptr->int_parm);
897 } else
898 tasklet_schedule(&q->tasklet);
899 }
889 900
890 if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) 901 if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED))
891 return; 902 return;
@@ -1519,6 +1530,129 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1519} 1530}
1520EXPORT_SYMBOL_GPL(do_QDIO); 1531EXPORT_SYMBOL_GPL(do_QDIO);
1521 1532
1533/**
1534 * qdio_start_irq - process input buffers
1535 * @cdev: associated ccw_device for the qdio subchannel
1536 * @nr: input queue number
1537 *
1538 * Return codes
1539 * 0 - success
1540 * 1 - irqs not started since new data is available
1541 */
1542int qdio_start_irq(struct ccw_device *cdev, int nr)
1543{
1544 struct qdio_q *q;
1545 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1546
1547 if (!irq_ptr)
1548 return -ENODEV;
1549 q = irq_ptr->input_qs[nr];
1550
1551 WARN_ON(queue_irqs_enabled(q));
1552
1553 if (!shared_ind(q->irq_ptr))
1554 xchg(q->irq_ptr->dsci, 0);
1555
1556 qdio_stop_polling(q);
1557 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
1558
1559 /*
1560 * We need to check again to not lose initiative after
1561 * resetting the ACK state.
1562 */
1563 if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci)
1564 goto rescan;
1565 if (!qdio_inbound_q_done(q))
1566 goto rescan;
1567 return 0;
1568
1569rescan:
1570 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
1571 &q->u.in.queue_irq_state))
1572 return 0;
1573 else
1574 return 1;
1575
1576}
1577EXPORT_SYMBOL(qdio_start_irq);
1578
1579/**
1580 * qdio_get_next_buffers - process input buffers
1581 * @cdev: associated ccw_device for the qdio subchannel
1582 * @nr: input queue number
1583 * @bufnr: first filled buffer number
1584 * @error: buffers are in error state
1585 *
1586 * Return codes
1587 * < 0 - error
1588 * = 0 - no new buffers found
1589 * > 0 - number of processed buffers
1590 */
1591int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
1592 int *error)
1593{
1594 struct qdio_q *q;
1595 int start, end;
1596 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1597
1598 if (!irq_ptr)
1599 return -ENODEV;
1600 q = irq_ptr->input_qs[nr];
1601 WARN_ON(queue_irqs_enabled(q));
1602
1603 qdio_sync_after_thinint(q);
1604
1605 /*
1606 * The interrupt could be caused by a PCI request. Check the
1607 * PCI capable outbound queues.
1608 */
1609 qdio_check_outbound_after_thinint(q);
1610
1611 if (!qdio_inbound_q_moved(q))
1612 return 0;
1613
1614 /* Note: upper-layer MUST stop processing immediately here ... */
1615 if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
1616 return -EIO;
1617
1618 start = q->first_to_kick;
1619 end = q->first_to_check;
1620 *bufnr = start;
1621 *error = q->qdio_error;
1622
1623 /* for the next time */
1624 q->first_to_kick = end;
1625 q->qdio_error = 0;
1626 return sub_buf(end, start);
1627}
1628EXPORT_SYMBOL(qdio_get_next_buffers);
1629
1630/**
1631 * qdio_stop_irq - disable interrupt processing for the device
1632 * @cdev: associated ccw_device for the qdio subchannel
1633 * @nr: input queue number
1634 *
1635 * Return codes
1636 * 0 - interrupts were already disabled
1637 * 1 - interrupts successfully disabled
1638 */
1639int qdio_stop_irq(struct ccw_device *cdev, int nr)
1640{
1641 struct qdio_q *q;
1642 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1643
1644 if (!irq_ptr)
1645 return -ENODEV;
1646 q = irq_ptr->input_qs[nr];
1647
1648 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
1649 &q->u.in.queue_irq_state))
1650 return 0;
1651 else
1652 return 1;
1653}
1654EXPORT_SYMBOL(qdio_stop_irq);
1655
1522static int __init init_QDIO(void) 1656static int __init init_QDIO(void)
1523{ 1657{
1524 int rc; 1658 int rc;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 34c7e4046df..a13cf7ec64b 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -161,6 +161,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
161 setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); 161 setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
162 162
163 q->is_input_q = 1; 163 q->is_input_q = 1;
164 q->u.in.queue_start_poll = qdio_init->queue_start_poll;
164 setup_storage_lists(q, irq_ptr, input_sbal_array, i); 165 setup_storage_lists(q, irq_ptr, input_sbal_array, i);
165 input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; 166 input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
166 167
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8daf1b99f15..752dbee06af 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -25,24 +25,20 @@
25 */ 25 */
26#define TIQDIO_NR_NONSHARED_IND 63 26#define TIQDIO_NR_NONSHARED_IND 63
27#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) 27#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1)
28#define TIQDIO_SHARED_IND 63
29 28
30/* list of thin interrupt input queues */ 29/* list of thin interrupt input queues */
31static LIST_HEAD(tiq_list); 30static LIST_HEAD(tiq_list);
32DEFINE_MUTEX(tiq_list_lock); 31DEFINE_MUTEX(tiq_list_lock);
33 32
34/* adapter local summary indicator */ 33/* adapter local summary indicator */
35static unsigned char *tiqdio_alsi; 34static u8 *tiqdio_alsi;
36 35
37/* device state change indicators */ 36struct indicator_t *q_indicators;
38struct indicator_t {
39 u32 ind; /* u32 because of compare-and-swap performance */
40 atomic_t count; /* use count, 0 or 1 for non-shared indicators */
41};
42static struct indicator_t *q_indicators;
43 37
44static int css_qdio_omit_svs; 38static int css_qdio_omit_svs;
45 39
40static u64 last_ai_time;
41
46static inline unsigned long do_clear_global_summary(void) 42static inline unsigned long do_clear_global_summary(void)
47{ 43{
48 register unsigned long __fn asm("1") = 3; 44 register unsigned long __fn asm("1") = 3;
@@ -116,59 +112,73 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
116 } 112 }
117} 113}
118 114
119static inline int shared_ind(struct qdio_irq *irq_ptr) 115static inline int shared_ind_used(void)
120{ 116{
121 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; 117 return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count);
122} 118}
123 119
124/** 120/**
125 * tiqdio_thinint_handler - thin interrupt handler for qdio 121 * tiqdio_thinint_handler - thin interrupt handler for qdio
126 * @ind: pointer to adapter local summary indicator 122 * @alsi: pointer to adapter local summary indicator
127 * @drv_data: NULL 123 * @data: NULL
128 */ 124 */
129static void tiqdio_thinint_handler(void *ind, void *drv_data) 125static void tiqdio_thinint_handler(void *alsi, void *data)
130{ 126{
131 struct qdio_q *q; 127 struct qdio_q *q;
132 128
129 last_ai_time = S390_lowcore.int_clock;
130
133 /* 131 /*
134 * SVS only when needed: issue SVS to benefit from iqdio interrupt 132 * SVS only when needed: issue SVS to benefit from iqdio interrupt
135 * avoidance (SVS clears adapter interrupt suppression overwrite) 133 * avoidance (SVS clears adapter interrupt suppression overwrite).
136 */ 134 */
137 if (!css_qdio_omit_svs) 135 if (!css_qdio_omit_svs)
138 do_clear_global_summary(); 136 do_clear_global_summary();
139 137
140 /* 138 /* reset local summary indicator */
141 * reset local summary indicator (tiqdio_alsi) to stop adapter 139 if (shared_ind_used())
142 * interrupts for now 140 xchg(tiqdio_alsi, 0);
143 */
144 xchg((u8 *)ind, 0);
145 141
146 /* protect tiq_list entries, only changed in activate or shutdown */ 142 /* protect tiq_list entries, only changed in activate or shutdown */
147 rcu_read_lock(); 143 rcu_read_lock();
148 144
149 /* check for work on all inbound thinint queues */ 145 /* check for work on all inbound thinint queues */
150 list_for_each_entry_rcu(q, &tiq_list, entry) 146 list_for_each_entry_rcu(q, &tiq_list, entry) {
147
151 /* only process queues from changed sets */ 148 /* only process queues from changed sets */
152 if (*q->irq_ptr->dsci) { 149 if (!*q->irq_ptr->dsci)
153 qperf_inc(q, adapter_int); 150 continue;
154 151
152 if (q->u.in.queue_start_poll) {
153 /* skip if polling is enabled or already in work */
154 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
155 &q->u.in.queue_irq_state)) {
156 qperf_inc(q, int_discarded);
157 continue;
158 }
159
160 /* avoid dsci clear here, done after processing */
161 q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
162 q->irq_ptr->int_parm);
163 } else {
155 /* only clear it if the indicator is non-shared */ 164 /* only clear it if the indicator is non-shared */
156 if (!shared_ind(q->irq_ptr)) 165 if (!shared_ind(q->irq_ptr))
157 xchg(q->irq_ptr->dsci, 0); 166 xchg(q->irq_ptr->dsci, 0);
158 /* 167 /*
159 * don't call inbound processing directly since 168 * Call inbound processing but not directly
160 * that could starve other thinint queues 169 * since that could starve other thinint queues.
161 */ 170 */
162 tasklet_schedule(&q->tasklet); 171 tasklet_schedule(&q->tasklet);
163 } 172 }
164 173 qperf_inc(q, adapter_int);
174 }
165 rcu_read_unlock(); 175 rcu_read_unlock();
166 176
167 /* 177 /*
168 * if we used the shared indicator clear it now after all queues 178 * If the shared indicator was used clear it now after all queues
169 * were processed 179 * were processed.
170 */ 180 */
171 if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) { 181 if (shared_ind_used()) {
172 xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); 182 xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0);
173 183
174 /* prevent racing */ 184 /* prevent racing */
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 977bb4d4ed1..456b1874339 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -100,6 +100,6 @@ config QETH_IPV6
100 100
101config CCWGROUP 101config CCWGROUP
102 tristate 102 tristate
103 default (LCS || CTCM || QETH) 103 default (LCS || CTCM || QETH || CLAW)
104 104
105endmenu 105endmenu
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 2861e78773c..b64881f33f2 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -540,7 +540,7 @@ void ctc_mpc_dealloc_ch(int port_num)
540 540
541 CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG, 541 CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG,
542 "%s: %s: refcount = %d\n", 542 "%s: %s: refcount = %d\n",
543 CTCM_FUNTAIL, dev->name, atomic_read(&dev->refcnt)); 543 CTCM_FUNTAIL, dev->name, netdev_refcnt_read(dev));
544 544
545 fsm_deltimer(&priv->restart_timer); 545 fsm_deltimer(&priv->restart_timer);
546 grp->channels_terminating = 0; 546 grp->channels_terminating = 0;
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index d1257768be9..6be43eb126b 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -676,6 +676,7 @@ enum qeth_discipline_id {
676}; 676};
677 677
678struct qeth_discipline { 678struct qeth_discipline {
679 void (*start_poll)(struct ccw_device *, int, unsigned long);
679 qdio_handler_t *input_handler; 680 qdio_handler_t *input_handler;
680 qdio_handler_t *output_handler; 681 qdio_handler_t *output_handler;
681 int (*recover)(void *ptr); 682 int (*recover)(void *ptr);
@@ -702,6 +703,16 @@ struct qeth_skb_data {
702#define QETH_SKB_MAGIC 0x71657468 703#define QETH_SKB_MAGIC 0x71657468
703#define QETH_SIGA_CC2_RETRIES 3 704#define QETH_SIGA_CC2_RETRIES 3
704 705
706struct qeth_rx {
707 int b_count;
708 int b_index;
709 struct qdio_buffer_element *b_element;
710 int e_offset;
711 int qdio_err;
712};
713
714#define QETH_NAPI_WEIGHT 128
715
705struct qeth_card { 716struct qeth_card {
706 struct list_head list; 717 struct list_head list;
707 enum qeth_card_states state; 718 enum qeth_card_states state;
@@ -749,6 +760,8 @@ struct qeth_card {
749 debug_info_t *debug; 760 debug_info_t *debug;
750 struct mutex conf_mutex; 761 struct mutex conf_mutex;
751 struct mutex discipline_mutex; 762 struct mutex discipline_mutex;
763 struct napi_struct napi;
764 struct qeth_rx rx;
752}; 765};
753 766
754struct qeth_card_list_struct { 767struct qeth_card_list_struct {
@@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
831 struct qdio_buffer *, struct qdio_buffer_element **, int *, 844 struct qdio_buffer *, struct qdio_buffer_element **, int *,
832 struct qeth_hdr **); 845 struct qeth_hdr **);
833void qeth_schedule_recovery(struct qeth_card *); 846void qeth_schedule_recovery(struct qeth_card *);
847void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
848void qeth_qdio_input_handler(struct ccw_device *,
849 unsigned int, unsigned int, int,
850 int, unsigned long);
834void qeth_qdio_output_handler(struct ccw_device *, unsigned int, 851void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
835 int, int, int, unsigned long); 852 int, int, int, unsigned long);
836void qeth_clear_ipacmd_list(struct qeth_card *); 853void qeth_clear_ipacmd_list(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3a5a18a0fc2..76426706260 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
2911 } 2911 }
2912} 2912}
2913 2913
2914void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
2915 unsigned long card_ptr)
2916{
2917 struct qeth_card *card = (struct qeth_card *)card_ptr;
2918
2919 if (card->dev)
2920 napi_schedule(&card->napi);
2921}
2922EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
2923
2924void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
2925 unsigned int queue, int first_element, int count,
2926 unsigned long card_ptr)
2927{
2928 struct qeth_card *card = (struct qeth_card *)card_ptr;
2929
2930 if (qdio_err)
2931 qeth_schedule_recovery(card);
2932}
2933EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
2934
2914void qeth_qdio_output_handler(struct ccw_device *ccwdev, 2935void qeth_qdio_output_handler(struct ccw_device *ccwdev,
2915 unsigned int qdio_error, int __queue, int first_element, 2936 unsigned int qdio_error, int __queue, int first_element,
2916 int count, unsigned long card_ptr) 2937 int count, unsigned long card_ptr)
@@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
3843 init_data.no_output_qs = card->qdio.no_out_queues; 3864 init_data.no_output_qs = card->qdio.no_out_queues;
3844 init_data.input_handler = card->discipline.input_handler; 3865 init_data.input_handler = card->discipline.input_handler;
3845 init_data.output_handler = card->discipline.output_handler; 3866 init_data.output_handler = card->discipline.output_handler;
3867 init_data.queue_start_poll = card->discipline.start_poll;
3846 init_data.int_parm = (unsigned long) card; 3868 init_data.int_parm = (unsigned long) card;
3847 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3869 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3848 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3870 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
@@ -4513,8 +4535,8 @@ static struct {
4513/* 20 */{"queue 1 buffer usage"}, 4535/* 20 */{"queue 1 buffer usage"},
4514 {"queue 2 buffer usage"}, 4536 {"queue 2 buffer usage"},
4515 {"queue 3 buffer usage"}, 4537 {"queue 3 buffer usage"},
4516 {"rx handler time"}, 4538 {"rx poll time"},
4517 {"rx handler count"}, 4539 {"rx poll count"},
4518 {"rx do_QDIO time"}, 4540 {"rx do_QDIO time"},
4519 {"rx do_QDIO count"}, 4541 {"rx do_QDIO count"},
4520 {"tx handler time"}, 4542 {"tx handler time"},
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 830d63524d6..847e8797073 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -310,6 +310,8 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
310 struct qeth_vlan_vid *id; 310 struct qeth_vlan_vid *id;
311 311
312 QETH_CARD_TEXT_(card, 4, "aid:%d", vid); 312 QETH_CARD_TEXT_(card, 4, "aid:%d", vid);
313 if (!vid)
314 return;
313 if (card->info.type == QETH_CARD_TYPE_OSM) { 315 if (card->info.type == QETH_CARD_TYPE_OSM) {
314 QETH_CARD_TEXT(card, 3, "aidOSM"); 316 QETH_CARD_TEXT(card, 3, "aidOSM");
315 return; 317 return;
@@ -407,29 +409,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
407 return rc; 409 return rc;
408} 410}
409 411
410static void qeth_l2_process_inbound_buffer(struct qeth_card *card, 412static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
411 struct qeth_qdio_buffer *buf, int index) 413 int budget, int *done)
412{ 414{
413 struct qdio_buffer_element *element; 415 int work_done = 0;
414 struct sk_buff *skb; 416 struct sk_buff *skb;
415 struct qeth_hdr *hdr; 417 struct qeth_hdr *hdr;
416 int offset;
417 unsigned int len; 418 unsigned int len;
418 419
419 /* get first element of current buffer */ 420 *done = 0;
420 element = (struct qdio_buffer_element *)&buf->buffer->element[0]; 421 BUG_ON(!budget);
421 offset = 0; 422 while (budget) {
422 if (card->options.performance_stats) 423 skb = qeth_core_get_next_skb(card,
423 card->perf_stats.bufs_rec++; 424 card->qdio.in_q->bufs[card->rx.b_index].buffer,
424 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, 425 &card->rx.b_element, &card->rx.e_offset, &hdr);
425 &offset, &hdr))) { 426 if (!skb) {
426 skb->dev = card->dev; 427 *done = 1;
427 /* is device UP ? */ 428 break;
428 if (!(card->dev->flags & IFF_UP)) {
429 dev_kfree_skb_any(skb);
430 continue;
431 } 429 }
432 430 skb->dev = card->dev;
433 switch (hdr->hdr.l2.id) { 431 switch (hdr->hdr.l2.id) {
434 case QETH_HEADER_TYPE_LAYER2: 432 case QETH_HEADER_TYPE_LAYER2:
435 skb->pkt_type = PACKET_HOST; 433 skb->pkt_type = PACKET_HOST;
@@ -441,7 +439,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
441 if (skb->protocol == htons(ETH_P_802_2)) 439 if (skb->protocol == htons(ETH_P_802_2))
442 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; 440 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
443 len = skb->len; 441 len = skb->len;
444 netif_rx(skb); 442 netif_receive_skb(skb);
445 break; 443 break;
446 case QETH_HEADER_TYPE_OSN: 444 case QETH_HEADER_TYPE_OSN:
447 if (card->info.type == QETH_CARD_TYPE_OSN) { 445 if (card->info.type == QETH_CARD_TYPE_OSN) {
@@ -459,9 +457,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
459 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); 457 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
460 continue; 458 continue;
461 } 459 }
460 work_done++;
461 budget--;
462 card->stats.rx_packets++; 462 card->stats.rx_packets++;
463 card->stats.rx_bytes += len; 463 card->stats.rx_bytes += len;
464 } 464 }
465 return work_done;
466}
467
468static int qeth_l2_poll(struct napi_struct *napi, int budget)
469{
470 struct qeth_card *card = container_of(napi, struct qeth_card, napi);
471 int work_done = 0;
472 struct qeth_qdio_buffer *buffer;
473 int done;
474 int new_budget = budget;
475
476 if (card->options.performance_stats) {
477 card->perf_stats.inbound_cnt++;
478 card->perf_stats.inbound_start_time = qeth_get_micros();
479 }
480
481 while (1) {
482 if (!card->rx.b_count) {
483 card->rx.qdio_err = 0;
484 card->rx.b_count = qdio_get_next_buffers(
485 card->data.ccwdev, 0, &card->rx.b_index,
486 &card->rx.qdio_err);
487 if (card->rx.b_count <= 0) {
488 card->rx.b_count = 0;
489 break;
490 }
491 card->rx.b_element =
492 &card->qdio.in_q->bufs[card->rx.b_index]
493 .buffer->element[0];
494 card->rx.e_offset = 0;
495 }
496
497 while (card->rx.b_count) {
498 buffer = &card->qdio.in_q->bufs[card->rx.b_index];
499 if (!(card->rx.qdio_err &&
500 qeth_check_qdio_errors(card, buffer->buffer,
501 card->rx.qdio_err, "qinerr")))
502 work_done += qeth_l2_process_inbound_buffer(
503 card, new_budget, &done);
504 else
505 done = 1;
506
507 if (done) {
508 if (card->options.performance_stats)
509 card->perf_stats.bufs_rec++;
510 qeth_put_buffer_pool_entry(card,
511 buffer->pool_entry);
512 qeth_queue_input_buffer(card, card->rx.b_index);
513 card->rx.b_count--;
514 if (card->rx.b_count) {
515 card->rx.b_index =
516 (card->rx.b_index + 1) %
517 QDIO_MAX_BUFFERS_PER_Q;
518 card->rx.b_element =
519 &card->qdio.in_q
520 ->bufs[card->rx.b_index]
521 .buffer->element[0];
522 card->rx.e_offset = 0;
523 }
524 }
525
526 if (work_done >= budget)
527 goto out;
528 else
529 new_budget = budget - work_done;
530 }
531 }
532
533 napi_complete(napi);
534 if (qdio_start_irq(card->data.ccwdev, 0))
535 napi_schedule(&card->napi);
536out:
537 if (card->options.performance_stats)
538 card->perf_stats.inbound_time += qeth_get_micros() -
539 card->perf_stats.inbound_start_time;
540 return work_done;
465} 541}
466 542
467static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, 543static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
@@ -755,49 +831,10 @@ tx_drop:
755 return NETDEV_TX_OK; 831 return NETDEV_TX_OK;
756} 832}
757 833
758static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
759 unsigned int qdio_err, unsigned int queue,
760 int first_element, int count, unsigned long card_ptr)
761{
762 struct net_device *net_dev;
763 struct qeth_card *card;
764 struct qeth_qdio_buffer *buffer;
765 int index;
766 int i;
767
768 card = (struct qeth_card *) card_ptr;
769 net_dev = card->dev;
770 if (card->options.performance_stats) {
771 card->perf_stats.inbound_cnt++;
772 card->perf_stats.inbound_start_time = qeth_get_micros();
773 }
774 if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
775 QETH_CARD_TEXT(card, 1, "qdinchk");
776 QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element,
777 count);
778 QETH_CARD_TEXT_(card, 1, "%04X", queue);
779 qeth_schedule_recovery(card);
780 return;
781 }
782 for (i = first_element; i < (first_element + count); ++i) {
783 index = i % QDIO_MAX_BUFFERS_PER_Q;
784 buffer = &card->qdio.in_q->bufs[index];
785 if (!(qdio_err &&
786 qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
787 "qinerr")))
788 qeth_l2_process_inbound_buffer(card, buffer, index);
789 /* clear buffer and give back to hardware */
790 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
791 qeth_queue_input_buffer(card, index);
792 }
793 if (card->options.performance_stats)
794 card->perf_stats.inbound_time += qeth_get_micros() -
795 card->perf_stats.inbound_start_time;
796}
797
798static int qeth_l2_open(struct net_device *dev) 834static int qeth_l2_open(struct net_device *dev)
799{ 835{
800 struct qeth_card *card = dev->ml_priv; 836 struct qeth_card *card = dev->ml_priv;
837 int rc = 0;
801 838
802 QETH_CARD_TEXT(card, 4, "qethopen"); 839 QETH_CARD_TEXT(card, 4, "qethopen");
803 if (card->state != CARD_STATE_SOFTSETUP) 840 if (card->state != CARD_STATE_SOFTSETUP)
@@ -814,18 +851,24 @@ static int qeth_l2_open(struct net_device *dev)
814 851
815 if (!card->lan_online && netif_carrier_ok(dev)) 852 if (!card->lan_online && netif_carrier_ok(dev))
816 netif_carrier_off(dev); 853 netif_carrier_off(dev);
817 return 0; 854 if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
855 napi_enable(&card->napi);
856 napi_schedule(&card->napi);
857 } else
858 rc = -EIO;
859 return rc;
818} 860}
819 861
820
821static int qeth_l2_stop(struct net_device *dev) 862static int qeth_l2_stop(struct net_device *dev)
822{ 863{
823 struct qeth_card *card = dev->ml_priv; 864 struct qeth_card *card = dev->ml_priv;
824 865
825 QETH_CARD_TEXT(card, 4, "qethstop"); 866 QETH_CARD_TEXT(card, 4, "qethstop");
826 netif_tx_disable(dev); 867 netif_tx_disable(dev);
827 if (card->state == CARD_STATE_UP) 868 if (card->state == CARD_STATE_UP) {
828 card->state = CARD_STATE_SOFTSETUP; 869 card->state = CARD_STATE_SOFTSETUP;
870 napi_disable(&card->napi);
871 }
829 return 0; 872 return 0;
830} 873}
831 874
@@ -836,8 +879,9 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
836 INIT_LIST_HEAD(&card->vid_list); 879 INIT_LIST_HEAD(&card->vid_list);
837 INIT_LIST_HEAD(&card->mc_list); 880 INIT_LIST_HEAD(&card->mc_list);
838 card->options.layer2 = 1; 881 card->options.layer2 = 1;
882 card->discipline.start_poll = qeth_qdio_start_poll;
839 card->discipline.input_handler = (qdio_handler_t *) 883 card->discipline.input_handler = (qdio_handler_t *)
840 qeth_l2_qdio_input_handler; 884 qeth_qdio_input_handler;
841 card->discipline.output_handler = (qdio_handler_t *) 885 card->discipline.output_handler = (qdio_handler_t *)
842 qeth_qdio_output_handler; 886 qeth_qdio_output_handler;
843 card->discipline.recover = qeth_l2_recover; 887 card->discipline.recover = qeth_l2_recover;
@@ -923,6 +967,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
923 card->info.broadcast_capable = 1; 967 card->info.broadcast_capable = 1;
924 qeth_l2_request_initial_mac(card); 968 qeth_l2_request_initial_mac(card);
925 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 969 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
970 netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
926 return register_netdev(card->dev); 971 return register_netdev(card->dev);
927} 972}
928 973
@@ -955,6 +1000,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
955 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); 1000 qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
956 1001
957 card->state = CARD_STATE_HARDSETUP; 1002 card->state = CARD_STATE_HARDSETUP;
1003 memset(&card->rx, 0, sizeof(struct qeth_rx));
958 qeth_print_status_message(card); 1004 qeth_print_status_message(card);
959 1005
960 /* softsetup */ 1006 /* softsetup */
@@ -1086,9 +1132,6 @@ static int qeth_l2_recover(void *ptr)
1086 card->use_hard_stop = 1; 1132 card->use_hard_stop = 1;
1087 __qeth_l2_set_offline(card->gdev, 1); 1133 __qeth_l2_set_offline(card->gdev, 1);
1088 rc = __qeth_l2_set_online(card->gdev, 1); 1134 rc = __qeth_l2_set_online(card->gdev, 1);
1089 /* don't run another scheduled recovery */
1090 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1091 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1092 if (!rc) 1135 if (!rc)
1093 dev_info(&card->gdev->dev, 1136 dev_info(&card->gdev->dev,
1094 "Device successfully recovered!\n"); 1137 "Device successfully recovered!\n");
@@ -1099,6 +1142,8 @@ static int qeth_l2_recover(void *ptr)
1099 dev_warn(&card->gdev->dev, "The qeth device driver " 1142 dev_warn(&card->gdev->dev, "The qeth device driver "
1100 "failed to recover an error on the device\n"); 1143 "failed to recover an error on the device\n");
1101 } 1144 }
1145 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
1146 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
1102 return 0; 1147 return 0;
1103} 1148}
1104 1149
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index e22ae248f61..74d1401a5d5 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr)
103 103
104void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) 104void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf)
105{ 105{
106 sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" 106 sprintf(buf, "%pI6", addr);
107 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
108 addr[0], addr[1], addr[2], addr[3],
109 addr[4], addr[5], addr[6], addr[7],
110 addr[8], addr[9], addr[10], addr[11],
111 addr[12], addr[13], addr[14], addr[15]);
112} 107}
113 108
114int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) 109int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr)
@@ -1825,7 +1820,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card)
1825 return; 1820 return;
1826 1821
1827 vg = card->vlangrp; 1822 vg = card->vlangrp;
1828 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 1823 for (i = 0; i < VLAN_N_VID; i++) {
1829 struct net_device *netdev = vlan_group_get_device(vg, i); 1824 struct net_device *netdev = vlan_group_get_device(vg, i);
1830 if (netdev == NULL || 1825 if (netdev == NULL ||
1831 !(netdev->flags & IFF_UP)) 1826 !(netdev->flags & IFF_UP))
@@ -1888,7 +1883,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
1888 return; 1883 return;
1889 1884
1890 vg = card->vlangrp; 1885 vg = card->vlangrp;
1891 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 1886 for (i = 0; i < VLAN_N_VID; i++) {
1892 struct net_device *netdev = vlan_group_get_device(vg, i); 1887 struct net_device *netdev = vlan_group_get_device(vg, i);
1893 if (netdev == NULL || 1888 if (netdev == NULL ||
1894 !(netdev->flags & IFF_UP)) 1889 !(netdev->flags & IFF_UP))
@@ -2018,13 +2013,14 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
2018 qeth_l3_set_multicast_list(card->dev); 2013 qeth_l3_set_multicast_list(card->dev);
2019} 2014}
2020 2015
2021static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, 2016static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
2022 struct sk_buff *skb, struct qeth_hdr *hdr) 2017 struct sk_buff *skb, struct qeth_hdr *hdr,
2018 unsigned short *vlan_id)
2023{ 2019{
2024 unsigned short vlan_id = 0;
2025 __be16 prot; 2020 __be16 prot;
2026 struct iphdr *ip_hdr; 2021 struct iphdr *ip_hdr;
2027 unsigned char tg_addr[MAX_ADDR_LEN]; 2022 unsigned char tg_addr[MAX_ADDR_LEN];
2023 int is_vlan = 0;
2028 2024
2029 if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { 2025 if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) {
2030 prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : 2026 prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
@@ -2087,8 +2083,9 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
2087 2083
2088 if (hdr->hdr.l3.ext_flags & 2084 if (hdr->hdr.l3.ext_flags &
2089 (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { 2085 (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
2090 vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? 2086 *vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME) ?
2091 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); 2087 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
2088 is_vlan = 1;
2092 } 2089 }
2093 2090
2094 switch (card->options.checksum_type) { 2091 switch (card->options.checksum_type) {
@@ -2109,54 +2106,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
2109 skb->ip_summed = CHECKSUM_NONE; 2106 skb->ip_summed = CHECKSUM_NONE;
2110 } 2107 }
2111 2108
2112 return vlan_id; 2109 return is_vlan;
2113} 2110}
2114 2111
2115static void qeth_l3_process_inbound_buffer(struct qeth_card *card, 2112static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
2116 struct qeth_qdio_buffer *buf, int index) 2113 int budget, int *done)
2117{ 2114{
2118 struct qdio_buffer_element *element; 2115 int work_done = 0;
2119 struct sk_buff *skb; 2116 struct sk_buff *skb;
2120 struct qeth_hdr *hdr; 2117 struct qeth_hdr *hdr;
2121 int offset;
2122 __u16 vlan_tag = 0; 2118 __u16 vlan_tag = 0;
2119 int is_vlan;
2123 unsigned int len; 2120 unsigned int len;
2124 /* get first element of current buffer */
2125 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
2126 offset = 0;
2127 if (card->options.performance_stats)
2128 card->perf_stats.bufs_rec++;
2129 while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element,
2130 &offset, &hdr))) {
2131 skb->dev = card->dev;
2132 /* is device UP ? */
2133 if (!(card->dev->flags & IFF_UP)) {
2134 dev_kfree_skb_any(skb);
2135 continue;
2136 }
2137 2121
2122 *done = 0;
2123 BUG_ON(!budget);
2124 while (budget) {
2125 skb = qeth_core_get_next_skb(card,
2126 card->qdio.in_q->bufs[card->rx.b_index].buffer,
2127 &card->rx.b_element, &card->rx.e_offset, &hdr);
2128 if (!skb) {
2129 *done = 1;
2130 break;
2131 }
2132 skb->dev = card->dev;
2138 switch (hdr->hdr.l3.id) { 2133 switch (hdr->hdr.l3.id) {
2139 case QETH_HEADER_TYPE_LAYER3: 2134 case QETH_HEADER_TYPE_LAYER3:
2140 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); 2135 is_vlan = qeth_l3_rebuild_skb(card, skb, hdr,
2136 &vlan_tag);
2141 len = skb->len; 2137 len = skb->len;
2142 if (vlan_tag && !card->options.sniffer) 2138 if (is_vlan && !card->options.sniffer)
2143 if (card->vlangrp) 2139 vlan_gro_receive(&card->napi, card->vlangrp,
2144 vlan_hwaccel_rx(skb, card->vlangrp, 2140 vlan_tag, skb);
2145 vlan_tag);
2146 else {
2147 dev_kfree_skb_any(skb);
2148 continue;
2149 }
2150 else 2141 else
2151 netif_rx(skb); 2142 napi_gro_receive(&card->napi, skb);
2152 break; 2143 break;
2153 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ 2144 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
2154 skb->pkt_type = PACKET_HOST; 2145 skb->pkt_type = PACKET_HOST;
2155 skb->protocol = eth_type_trans(skb, skb->dev); 2146 skb->protocol = eth_type_trans(skb, skb->dev);
2156 if (card->options.checksum_type == NO_CHECKSUMMING)
2157 skb->ip_summed = CHECKSUM_UNNECESSARY;
2158 else
2159 skb->ip_summed = CHECKSUM_NONE;
2160 len = skb->len; 2147 len = skb->len;
2161 netif_receive_skb(skb); 2148 netif_receive_skb(skb);
2162 break; 2149 break;
@@ -2166,10 +2153,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2166 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); 2153 QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
2167 continue; 2154 continue;
2168 } 2155 }
2169 2156 work_done++;
2157 budget--;
2170 card->stats.rx_packets++; 2158 card->stats.rx_packets++;
2171 card->stats.rx_bytes += len; 2159 card->stats.rx_bytes += len;
2172 } 2160 }
2161 return work_done;
2162}
2163
2164static int qeth_l3_poll(struct napi_struct *napi, int budget)
2165{
2166 struct qeth_card *card = container_of(napi, struct qeth_card, napi);
2167 int work_done = 0;
2168 struct qeth_qdio_buffer *buffer;
2169 int done;
2170 int new_budget = budget;
2171
2172 if (card->options.performance_stats) {
2173 card->perf_stats.inbound_cnt++;
2174 card->perf_stats.inbound_start_time = qeth_get_micros();
2175 }
2176
2177 while (1) {
2178 if (!card->rx.b_count) {
2179 card->rx.qdio_err = 0;
2180 card->rx.b_count = qdio_get_next_buffers(
2181 card->data.ccwdev, 0, &card->rx.b_index,
2182 &card->rx.qdio_err);
2183 if (card->rx.b_count <= 0) {
2184 card->rx.b_count = 0;
2185 break;
2186 }
2187 card->rx.b_element =
2188 &card->qdio.in_q->bufs[card->rx.b_index]
2189 .buffer->element[0];
2190 card->rx.e_offset = 0;
2191 }
2192
2193 while (card->rx.b_count) {
2194 buffer = &card->qdio.in_q->bufs[card->rx.b_index];
2195 if (!(card->rx.qdio_err &&
2196 qeth_check_qdio_errors(card, buffer->buffer,
2197 card->rx.qdio_err, "qinerr")))
2198 work_done += qeth_l3_process_inbound_buffer(
2199 card, new_budget, &done);
2200 else
2201 done = 1;
2202
2203 if (done) {
2204 if (card->options.performance_stats)
2205 card->perf_stats.bufs_rec++;
2206 qeth_put_buffer_pool_entry(card,
2207 buffer->pool_entry);
2208 qeth_queue_input_buffer(card, card->rx.b_index);
2209 card->rx.b_count--;
2210 if (card->rx.b_count) {
2211 card->rx.b_index =
2212 (card->rx.b_index + 1) %
2213 QDIO_MAX_BUFFERS_PER_Q;
2214 card->rx.b_element =
2215 &card->qdio.in_q
2216 ->bufs[card->rx.b_index]
2217 .buffer->element[0];
2218 card->rx.e_offset = 0;
2219 }
2220 }
2221
2222 if (work_done >= budget)
2223 goto out;
2224 else
2225 new_budget = budget - work_done;
2226 }
2227 }
2228
2229 napi_complete(napi);
2230 if (qdio_start_irq(card->data.ccwdev, 0))
2231 napi_schedule(&card->napi);
2232out:
2233 if (card->options.performance_stats)
2234 card->perf_stats.inbound_time += qeth_get_micros() -
2235 card->perf_stats.inbound_start_time;
2236 return work_done;
2173} 2237}
2174 2238
2175static int qeth_l3_verify_vlan_dev(struct net_device *dev, 2239static int qeth_l3_verify_vlan_dev(struct net_device *dev,
@@ -2183,7 +2247,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev,
2183 if (!vg) 2247 if (!vg)
2184 return rc; 2248 return rc;
2185 2249
2186 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 2250 for (i = 0; i < VLAN_N_VID; i++) {
2187 if (vlan_group_get_device(vg, i) == dev) { 2251 if (vlan_group_get_device(vg, i) == dev) {
2188 rc = QETH_VLAN_CARD; 2252 rc = QETH_VLAN_CARD;
2189 break; 2253 break;
@@ -3103,6 +3167,7 @@ tx_drop:
3103static int qeth_l3_open(struct net_device *dev) 3167static int qeth_l3_open(struct net_device *dev)
3104{ 3168{
3105 struct qeth_card *card = dev->ml_priv; 3169 struct qeth_card *card = dev->ml_priv;
3170 int rc = 0;
3106 3171
3107 QETH_CARD_TEXT(card, 4, "qethopen"); 3172 QETH_CARD_TEXT(card, 4, "qethopen");
3108 if (card->state != CARD_STATE_SOFTSETUP) 3173 if (card->state != CARD_STATE_SOFTSETUP)
@@ -3113,7 +3178,12 @@ static int qeth_l3_open(struct net_device *dev)
3113 3178
3114 if (!card->lan_online && netif_carrier_ok(dev)) 3179 if (!card->lan_online && netif_carrier_ok(dev))
3115 netif_carrier_off(dev); 3180 netif_carrier_off(dev);
3116 return 0; 3181 if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
3182 napi_enable(&card->napi);
3183 napi_schedule(&card->napi);
3184 } else
3185 rc = -EIO;
3186 return rc;
3117} 3187}
3118 3188
3119static int qeth_l3_stop(struct net_device *dev) 3189static int qeth_l3_stop(struct net_device *dev)
@@ -3122,8 +3192,10 @@ static int qeth_l3_stop(struct net_device *dev)
3122 3192
3123 QETH_CARD_TEXT(card, 4, "qethstop"); 3193 QETH_CARD_TEXT(card, 4, "qethstop");
3124 netif_tx_disable(dev); 3194 netif_tx_disable(dev);
3125 if (card->state == CARD_STATE_UP) 3195 if (card->state == CARD_STATE_UP) {
3126 card->state = CARD_STATE_SOFTSETUP; 3196 card->state = CARD_STATE_SOFTSETUP;
3197 napi_disable(&card->napi);
3198 }
3127 return 0; 3199 return 0;
3128} 3200}
3129 3201
@@ -3293,57 +3365,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
3293 card->dev->gso_max_size = 15 * PAGE_SIZE; 3365 card->dev->gso_max_size = 15 * PAGE_SIZE;
3294 3366
3295 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 3367 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
3368 netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
3296 return register_netdev(card->dev); 3369 return register_netdev(card->dev);
3297} 3370}
3298 3371
3299static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
3300 unsigned int qdio_err, unsigned int queue, int first_element,
3301 int count, unsigned long card_ptr)
3302{
3303 struct net_device *net_dev;
3304 struct qeth_card *card;
3305 struct qeth_qdio_buffer *buffer;
3306 int index;
3307 int i;
3308
3309 card = (struct qeth_card *) card_ptr;
3310 net_dev = card->dev;
3311 if (card->options.performance_stats) {
3312 card->perf_stats.inbound_cnt++;
3313 card->perf_stats.inbound_start_time = qeth_get_micros();
3314 }
3315 if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
3316 QETH_CARD_TEXT(card, 1, "qdinchk");
3317 QETH_CARD_TEXT_(card, 1, "%04X%04X",
3318 first_element, count);
3319 QETH_CARD_TEXT_(card, 1, "%04X", queue);
3320 qeth_schedule_recovery(card);
3321 return;
3322 }
3323 for (i = first_element; i < (first_element + count); ++i) {
3324 index = i % QDIO_MAX_BUFFERS_PER_Q;
3325 buffer = &card->qdio.in_q->bufs[index];
3326 if (!(qdio_err &&
3327 qeth_check_qdio_errors(card, buffer->buffer,
3328 qdio_err, "qinerr")))
3329 qeth_l3_process_inbound_buffer(card, buffer, index);
3330 /* clear buffer and give back to hardware */
3331 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
3332 qeth_queue_input_buffer(card, index);
3333 }
3334 if (card->options.performance_stats)
3335 card->perf_stats.inbound_time += qeth_get_micros() -
3336 card->perf_stats.inbound_start_time;
3337}
3338
3339static int qeth_l3_probe_device(struct ccwgroup_device *gdev) 3372static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
3340{ 3373{
3341 struct qeth_card *card = dev_get_drvdata(&gdev->dev); 3374 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3342 3375
3343 qeth_l3_create_device_attributes(&gdev->dev); 3376 qeth_l3_create_device_attributes(&gdev->dev);
3344 card->options.layer2 = 0; 3377 card->options.layer2 = 0;
3378 card->discipline.start_poll = qeth_qdio_start_poll;
3345 card->discipline.input_handler = (qdio_handler_t *) 3379 card->discipline.input_handler = (qdio_handler_t *)
3346 qeth_l3_qdio_input_handler; 3380 qeth_qdio_input_handler;
3347 card->discipline.output_handler = (qdio_handler_t *) 3381 card->discipline.output_handler = (qdio_handler_t *)
3348 qeth_qdio_output_handler; 3382 qeth_qdio_output_handler;
3349 card->discipline.recover = qeth_l3_recover; 3383 card->discipline.recover = qeth_l3_recover;
@@ -3402,6 +3436,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3402 } 3436 }
3403 3437
3404 card->state = CARD_STATE_HARDSETUP; 3438 card->state = CARD_STATE_HARDSETUP;
3439 memset(&card->rx, 0, sizeof(struct qeth_rx));
3405 qeth_print_status_message(card); 3440 qeth_print_status_message(card);
3406 3441
3407 /* softsetup */ 3442 /* softsetup */
@@ -3538,9 +3573,6 @@ static int qeth_l3_recover(void *ptr)
3538 card->use_hard_stop = 1; 3573 card->use_hard_stop = 1;
3539 __qeth_l3_set_offline(card->gdev, 1); 3574 __qeth_l3_set_offline(card->gdev, 1);
3540 rc = __qeth_l3_set_online(card->gdev, 1); 3575 rc = __qeth_l3_set_online(card->gdev, 1);
3541 /* don't run another scheduled recovery */
3542 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3543 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
3544 if (!rc) 3576 if (!rc)
3545 dev_info(&card->gdev->dev, 3577 dev_info(&card->gdev->dev,
3546 "Device successfully recovered!\n"); 3578 "Device successfully recovered!\n");
@@ -3551,6 +3583,8 @@ static int qeth_l3_recover(void *ptr)
3551 dev_warn(&card->gdev->dev, "The qeth device driver " 3583 dev_warn(&card->gdev->dev, "The qeth device driver "
3552 "failed to recover an error on the device\n"); 3584 "failed to recover an error on the device\n");
3553 } 3585 }
3586 qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
3587 qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
3554 return 0; 3588 return 0;
3555} 3589}
3556 3590
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 60e6e5714eb..a0554beb417 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -279,16 +279,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
279static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, 279static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
280 struct zfcp_qdio *qdio) 280 struct zfcp_qdio *qdio)
281{ 281{
282 282 memset(id, 0, sizeof(*id));
283 id->cdev = qdio->adapter->ccw_device; 283 id->cdev = qdio->adapter->ccw_device;
284 id->q_format = QDIO_ZFCP_QFMT; 284 id->q_format = QDIO_ZFCP_QFMT;
285 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); 285 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
286 ASCEBC(id->adapter_name, 8); 286 ASCEBC(id->adapter_name, 8);
287 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; 287 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
288 id->qib_param_field_format = 0;
289 id->qib_param_field = NULL;
290 id->input_slib_elements = NULL;
291 id->output_slib_elements = NULL;
292 id->no_input_qs = 1; 288 id->no_input_qs = 1;
293 id->no_output_qs = 1; 289 id->no_output_qs = 1;
294 id->input_handler = zfcp_qdio_int_resp; 290 id->input_handler = zfcp_qdio_int_resp;