rocker: introduce interrupt credits

Introduce a new desc ring property "credits" which tracks outstanding desc
count that has yet to be processed by SW (the driver).  This provides an
efficient, race-free method for SW and HW to communicate work-to-do and
work-done.  HW will guarantee interrupts are generated when new work is posted
to the ring and 1) SW is idle or 2) SW processes fewer descs than HW has
posted.  A credit unit is a desc.  SW, in response to an interrupt, process the
descs marked done and returns a count (the credits) of how many descs where
processed via a PIO write to ring register (CREDITS).  HW, when generating the
interrupt, does an auto-mask on the interrupt vector, effectively disabling the
interrupt.  When SW has returned enough credits to catch up with HW, the
interrupt is auto-unmasked.  If SW returns credits, but is still behind HW, an
interrupt is generated and auto-masked again.  This last case ensures no
interrupts are missed by SW.

Event and cmd rings will typically process one desc per interrupt, so one
credit is returned and the interrupt is re-armed.  Tx and Rx rings, especially
when processed in batch mode with interrupts disabled (ala NAPI) can return
many credits in one shot (ala NAPI quota), and interrupts will only be
generated to keep the polling process sustained.  In the ISR, SW does not need
to mask the interrupt source at the CPU or the device, since the HW
automatically masked the interrupt pending the return of outstanding credits.

Credit method provides these benifits:

1) Returning credits by SW is a PIO write which is efficient on the PCIe bus.

2) SW does not need to mask the interrupt source at the CPU/PIC or the device.

3) For debugging purposes, SW can read outstanding credits on a given ring.

4) HW guarentees SW will not miss an interrupt.

5) HW guarentees no unnecessary interrupts are generated.

6) SW processing model is as simple as it can get.  For simple ISR functions,
SW loops over completed descs and returns credits.  For batch processing, the
ISR schedules polling and the polling thread processes completed descs and
returns credits.  If HW still has more work pending, or if HW gets new work
later, another interrupt is generated, restarting the polling process.

Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>