Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: ipa: initialize ring indexes to 0

When a GSI channel is initially allocated, and after it has been
reset, the hardware assumes its ring index is 0. And although we
do initialize channels this way, the comments in the IPA code don't
really explain this. For event rings, it doesn't matter what value
we use initially, so using 0 is just fine.

Add some information about the assumptions made by hardware above
the definition of the gsi_ring structure in "gsi.h".

Zero the index field for all rings (channel and event) when the ring
is allocated. As a result, that function initializes all fields in
the structure.

Stop zeroing the index the top of gsi_channel_program(). Initially
we'll use the index value set when the channel ring was allocated.
And we'll explicitly zero the index value in gsi_channel_reset()
before programming the hardware, adding a comment explaining why
it's required.

For event rings, use the index initialized by gsi_ring_alloc()
rather than 0 when ringing the doorbell in gsi_evt_ring_program().
(It'll still be zero, but we won't assume that to be the case.)

Use a local variable in gsi_evt_ring_program() that represents the
address of the event ring's ring structure.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Alex Elder and committed by
David S. Miller
5fb859f7 52323ef7

+13 -10
+10 -8
drivers/net/ipa/gsi.c
··· 665 665 static void gsi_evt_ring_program(struct gsi *gsi, u32 evt_ring_id) 666 666 { 667 667 struct gsi_evt_ring *evt_ring = &gsi->evt_ring[evt_ring_id]; 668 - size_t size = evt_ring->ring.count * GSI_RING_ELEMENT_SIZE; 668 + struct gsi_ring *ring = &evt_ring->ring; 669 + size_t size; 669 670 u32 val; 670 671 671 672 /* We program all event rings as GPI type/protocol */ ··· 675 674 val |= u32_encode_bits(GSI_RING_ELEMENT_SIZE, EV_ELEMENT_SIZE_FMASK); 676 675 iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_0_OFFSET(evt_ring_id)); 677 676 677 + size = ring->count * GSI_RING_ELEMENT_SIZE; 678 678 val = ev_r_length_encoded(gsi->version, size); 679 679 iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_1_OFFSET(evt_ring_id)); 680 680 ··· 683 681 * high-order 32 bits of the address of the event ring, 684 682 * respectively. 685 683 */ 686 - val = lower_32_bits(evt_ring->ring.addr); 684 + val = lower_32_bits(ring->addr); 687 685 iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_2_OFFSET(evt_ring_id)); 688 - val = upper_32_bits(evt_ring->ring.addr); 686 + val = upper_32_bits(ring->addr); 689 687 iowrite32(val, gsi->virt + GSI_EV_CH_E_CNTXT_3_OFFSET(evt_ring_id)); 690 688 691 689 /* Enable interrupt moderation by setting the moderation delay */ ··· 702 700 iowrite32(0, gsi->virt + GSI_EV_CH_E_CNTXT_12_OFFSET(evt_ring_id)); 703 701 iowrite32(0, gsi->virt + GSI_EV_CH_E_CNTXT_13_OFFSET(evt_ring_id)); 704 702 705 - /* Finally, tell the hardware we've completed event 0 (arbitrary) */ 706 - gsi_evt_ring_doorbell(gsi, evt_ring_id, 0); 703 + /* Finally, tell the hardware our "last processed" event (arbitrary) */ 704 + gsi_evt_ring_doorbell(gsi, evt_ring_id, ring->index); 707 705 } 708 706 709 707 /* Find the transaction whose completion indicates a channel is quiesced */ ··· 771 769 struct gsi *gsi = channel->gsi; 772 770 u32 wrr_weight = 0; 773 771 u32 val; 774 - 775 - /* Arbitrarily pick TRE 0 as the first channel element to use */ 776 - channel->tre_ring.index = 0; 777 772 778 773 /* We program all channels as GPI type/protocol */ 779 774 val = chtype_protocol_encoded(gsi->version, GSI_CHANNEL_TYPE_GPI); ··· 948 949 if (gsi->version < IPA_VERSION_4_0 && !channel->toward_ipa) 949 950 gsi_channel_reset_command(channel); 950 951 952 + /* Hardware assumes this is 0 following reset */ 953 + channel->tre_ring.index = 0; 951 954 gsi_channel_program(channel, doorbell); 952 955 gsi_channel_trans_cancel_pending(channel); 953 956 ··· 1434 1433 1435 1434 ring->addr = addr; 1436 1435 ring->count = count; 1436 + ring->index = 0; 1437 1437 1438 1438 return 0; 1439 1439 }
+3 -2
drivers/net/ipa/gsi.h
··· 48 48 * 49 49 * A channel ring consists of TRE entries filled by the AP and passed 50 50 * to the hardware for processing. For a channel ring, the ring index 51 - * identifies the next unused entry to be filled by the AP. 51 + * identifies the next unused entry to be filled by the AP. In this 52 + * case the initial value is assumed by hardware to be 0. 52 53 * 53 54 * An event ring consists of event structures filled by the hardware 54 55 * and passed to the AP. For event rings, the ring index identifies 55 56 * the next ring entry that is not known to have been filled by the 56 - * hardware. 57 + * hardware. The initial value used is arbitrary (so we use 0). 57 58 */ 58 59 u32 index; 59 60 };