Commit 1455ea1d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 's390-next'



Julian Wiedmann says:

====================
s390/qeth: updates 2020-03-25

please apply the following patch series for qeth to netdev's net-next
tree.
Same series as yesterday, with one minor update to patch 1 as per
your review.

This adds
1) NAPI poll support for the async-Completion Queue (with one qdio layer
   patch acked by Heiko),
2) ethtool support for per-queue TX IRQ coalescing,
3) various cleanups.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 29f3490b bb59c8a8
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -338,7 +338,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
 * @no_output_qs: number of output queues
 * @input_handler: handler to be called for input queues
 * @output_handler: handler to be called for output queues
 * @queue_start_poll_array: polling handlers (one per input queue or NULL)
 * @irq_poll: Data IRQ polling handler (NULL when not supported)
 * @scan_threshold: # of in-use buffers that triggers scan on output queue
 * @int_parm: interruption parameter
 * @input_sbal_addr_array:  address of no_input_qs * 128 pointers
@@ -359,8 +359,7 @@ struct qdio_initialize {
	unsigned int no_output_qs;
	qdio_handler_t *input_handler;
	qdio_handler_t *output_handler;
	void (**queue_start_poll_array) (struct ccw_device *, int,
					  unsigned long);
	void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
	unsigned int scan_threshold;
	unsigned long int_parm;
	struct qdio_buffer **input_sbal_addr_array;
@@ -415,8 +414,8 @@ extern int qdio_activate(struct ccw_device *);
extern void qdio_release_aob(struct qaob *);
extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
		   unsigned int);
extern int qdio_start_irq(struct ccw_device *, int);
extern int qdio_stop_irq(struct ccw_device *, int);
extern int qdio_start_irq(struct ccw_device *cdev);
extern int qdio_stop_irq(struct ccw_device *cdev);
extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *);
extern int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr,
			      bool is_input, unsigned int *bufnr,
+5 −6
Original line number Diff line number Diff line
@@ -177,8 +177,8 @@ struct qdio_queue_perf_stat {
	unsigned int nr_sbal_total;
};

enum qdio_queue_irq_states {
	QDIO_QUEUE_IRQS_DISABLED,
enum qdio_irq_poll_states {
	QDIO_IRQ_DISABLED,
};

struct qdio_input_q {
@@ -188,10 +188,6 @@ struct qdio_input_q {
	int ack_count;
	/* last time of noticing incoming data */
	u64 timestamp;
	/* upper-layer polling flag */
	unsigned long queue_irq_state;
	/* callback to start upper-layer polling */
	void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
};

struct qdio_output_q {
@@ -299,6 +295,9 @@ struct qdio_irq {
	struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
	struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];

	void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
	unsigned long poll_state;

	debug_info_t *debug_area;
	struct mutex setup_mutex;
	struct qdio_dev_perf_stat perf_stat;
+2 −2
Original line number Diff line number Diff line
@@ -128,8 +128,8 @@ static int qstat_show(struct seq_file *m, void *v)
			   q->u.in.ack_start, q->u.in.ack_count);
		seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
			   *(u8 *)q->irq_ptr->dsci,
			   test_bit(QDIO_QUEUE_IRQS_DISABLED,
			   &q->u.in.queue_irq_state));
			   test_bit(QDIO_IRQ_DISABLED,
				    &q->irq_ptr->poll_state));
	}
	seq_printf(m, "SBAL states:\n");
	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
+23 −27
Original line number Diff line number Diff line
@@ -950,20 +950,15 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
	if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
		return;

	for_each_input_queue(irq_ptr, q, i) {
		if (q->u.in.queue_start_poll) {
			/* skip if polling is enabled or already in work */
			if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
				     &q->u.in.queue_irq_state)) {
	if (irq_ptr->irq_poll) {
		if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
			irq_ptr->irq_poll(irq_ptr->cdev, irq_ptr->int_parm);
		else
			QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
				continue;
			}
			q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
						 q->irq_ptr->int_parm);
	} else {
		for_each_input_queue(irq_ptr, q, i)
			tasklet_schedule(&q->tasklet);
	}
	}

	if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold)
		return;
@@ -1610,24 +1605,26 @@ EXPORT_SYMBOL_GPL(do_QDIO);
/**
 * qdio_start_irq - process input buffers
 * @cdev: associated ccw_device for the qdio subchannel
 * @nr: input queue number
 *
 * Return codes
 *   0 - success
 *   1 - irqs not started since new data is available
 */
int qdio_start_irq(struct ccw_device *cdev, int nr)
int qdio_start_irq(struct ccw_device *cdev)
{
	struct qdio_q *q;
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
	unsigned int i;

	if (!irq_ptr)
		return -ENODEV;
	q = irq_ptr->input_qs[nr];

	clear_nonshared_ind(irq_ptr);

	for_each_input_queue(irq_ptr, q, i)
		qdio_stop_polling(q);
	clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);

	clear_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);

	/*
	 * We need to check again to not lose initiative after
@@ -1635,13 +1632,16 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
	 */
	if (test_nonshared_ind(irq_ptr))
		goto rescan;

	for_each_input_queue(irq_ptr, q, i) {
		if (!qdio_inbound_q_done(q, q->first_to_check))
			goto rescan;
	}

	return 0;

rescan:
	if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
			     &q->u.in.queue_irq_state))
	if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
		return 0;
	else
		return 1;
@@ -1729,23 +1729,19 @@ EXPORT_SYMBOL(qdio_get_next_buffers);
/**
 * qdio_stop_irq - disable interrupt processing for the device
 * @cdev: associated ccw_device for the qdio subchannel
 * @nr: input queue number
 *
 * Return codes
 *   0 - interrupts were already disabled
 *   1 - interrupts successfully disabled
 */
int qdio_stop_irq(struct ccw_device *cdev, int nr)
int qdio_stop_irq(struct ccw_device *cdev)
{
	struct qdio_q *q;
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

	if (!irq_ptr)
		return -ENODEV;
	q = irq_ptr->input_qs[nr];

	if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
			     &q->u.in.queue_irq_state))
	if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
		return 0;
	else
		return 1;
+7 −9
Original line number Diff line number Diff line
@@ -224,15 +224,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
		setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);

		q->is_input_q = 1;
		if (qdio_init->queue_start_poll_array &&
		    qdio_init->queue_start_poll_array[i]) {
			q->u.in.queue_start_poll =
				qdio_init->queue_start_poll_array[i];
			set_bit(QDIO_QUEUE_IRQS_DISABLED,
				&q->u.in.queue_irq_state);
		} else {
			q->u.in.queue_start_poll = NULL;
		}

		setup_storage_lists(q, irq_ptr, input_sbal_array, i);
		input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
@@ -483,6 +474,13 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
	ccw_device_get_schid(irq_ptr->cdev, &irq_ptr->schid);
	setup_queues(irq_ptr, init_data);

	if (init_data->irq_poll) {
		irq_ptr->irq_poll = init_data->irq_poll;
		set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
	} else {
		irq_ptr->irq_poll = NULL;
	}

	setup_qib(irq_ptr, init_data);
	qdio_setup_thinint(irq_ptr);
	set_impl_params(irq_ptr, init_data->qib_param_field_format,
Loading