Commit 7dd9558f authored by Alex Elder's avatar Alex Elder Committed by David S. Miller

net: ipa: determine channel from event

Each event in an event ring describes the TRE whose completion
caused the event.  Currently, every event ring is dedicated to a
single channel, so the channel is easily derived from the event
ring.

An event ring can actually be shared by more than one channel
though, and to distinguish events for one channel from another, the
event structure contains a field indicating which channel the event
is associated with.

In gsi_event_trans(), use the channel ID in an event to determine
which channel the event is for.  This makes the channel pointer now
passed to that function irrelevant; pass the GSI pointer to that
function instead.

And although it shouldn't happen, warn if an event arrives that
records a channel ID that's not in use, or if the event does not
have a transaction associated with it.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 983a1a30
...@@ -1327,17 +1327,29 @@ static int gsi_irq_init(struct gsi *gsi, struct platform_device *pdev) ...@@ -1327,17 +1327,29 @@ static int gsi_irq_init(struct gsi *gsi, struct platform_device *pdev)
} }
/* Return the transaction associated with a transfer completion event */ /* Return the transaction associated with a transfer completion event */
static struct gsi_trans *gsi_event_trans(struct gsi_channel *channel, static struct gsi_trans *
struct gsi_event *event) gsi_event_trans(struct gsi *gsi, struct gsi_event *event)
{ {
u32 channel_id = event->chid;
struct gsi_channel *channel;
struct gsi_trans *trans;
u32 tre_offset; u32 tre_offset;
u32 tre_index; u32 tre_index;
channel = &gsi->channel[channel_id];
if (WARN(!channel->gsi, "event has bad channel %u\n", channel_id))
return NULL;
/* Event xfer_ptr records the TRE it's associated with */ /* Event xfer_ptr records the TRE it's associated with */
tre_offset = lower_32_bits(le64_to_cpu(event->xfer_ptr)); tre_offset = lower_32_bits(le64_to_cpu(event->xfer_ptr));
tre_index = gsi_ring_index(&channel->tre_ring, tre_offset); tre_index = gsi_ring_index(&channel->tre_ring, tre_offset);
return gsi_channel_trans_mapped(channel, tre_index); trans = gsi_channel_trans_mapped(channel, tre_index);
if (WARN(!trans, "channel %u event with no transaction\n", channel_id))
return NULL;
return trans;
} }
/** /**
...@@ -1381,7 +1393,9 @@ static void gsi_evt_ring_rx_update(struct gsi_evt_ring *evt_ring, u32 index) ...@@ -1381,7 +1393,9 @@ static void gsi_evt_ring_rx_update(struct gsi_evt_ring *evt_ring, u32 index)
*/ */
old_index = ring->index; old_index = ring->index;
event = gsi_ring_virt(ring, old_index); event = gsi_ring_virt(ring, old_index);
trans = gsi_event_trans(channel, event); trans = gsi_event_trans(channel->gsi, event);
if (!trans)
return;
/* Compute the number of events to process before we wrap, /* Compute the number of events to process before we wrap,
* and determine when we'll be done processing events. * and determine when we'll be done processing events.
...@@ -1493,7 +1507,9 @@ static struct gsi_trans *gsi_channel_update(struct gsi_channel *channel) ...@@ -1493,7 +1507,9 @@ static struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)
return NULL; return NULL;
/* Get the transaction for the latest completed event. */ /* Get the transaction for the latest completed event. */
trans = gsi_event_trans(channel, gsi_ring_virt(ring, index - 1)); trans = gsi_event_trans(gsi, gsi_ring_virt(ring, index - 1));
if (!trans)
return NULL;
/* For RX channels, update each completed transaction with the number /* For RX channels, update each completed transaction with the number
* of bytes that were actually received. For TX channels, report * of bytes that were actually received. For TX channels, report
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment