sze2
Documentation

Properties:

1 Use Case View use_case

module_UC



Class OS
Class hardware
Class module

1.1 Use Case open_node

1. the module's device node is opened
2. per application descriptor allocation is done including space for status structure
3. if (not allocate_on_modpobe and refcount was 0) then call alloc_rings
4. node is mmap-ed (offset 0) -- status
5. node is mmap-ed with values from previously mapped memory (rx, tx spaces) -- note that all buffers are visible as a virtual contiguos memory. The only difference between TX and RX mmio space is read/write protection

1.2 Use Case subscribe

Precondition
Node must be opened yet and close must not to be in progress

Normal flow
1. subscribe_area ioctl is called with areas bitmap and poll_thresh; both for each direction
2. APP poll_thresh and areas are set to the status page

1.3 Use Case start

Precondition
Node must be opened yet and close must not to be in progress

Normal flow
1. start ioctl is called
2. each APP rx_tail_ptr and APP rx_head_ptr is set to the current corresponding HW rx_tail_ptr
3. if (refcount was 0) then the device is started -- enabling of interrupts, capture start ...

1.4 Use Case wait_for_data

Precondition
Node must be opened yet and close must not to be in progress

Normal flow
1. poll is invoked
2. while:
a) for all requested rx areas: difference(HW rx_head_ptr, APP rx_tail_ptr) < APP rx_poll_thresh and
b) for all requested tx areas: (tx_ring_size - difference(HW tx_head_ptr, HW tx_tail_ptr)) < APP tx_poll_thresh
do: the proccess is slept and interrupt scheduled
3. return status to the application

Alternative flow
* signal is catched while sleeping -> interrupt waiting and return

1.5 Use Case get_data

Precondition
Node must be opened yet and close must not to be in progress

Normal flow
1. rx_lock_data ioctl is invoked with requested areas bitmap
2. the requested bitmap is logically ANDed with the subscribed bitmap
3. size is computed as difference(APP rx_tail_ptr, HW rx_head_ptr) for each area until size is zero and this area number is stored
4. the size (even 0 is valid) is stored into the status page along with offset obtained from APP rx_tail_ptr
5. offset + size sum is stored into the right APP rx_head_ptr
6. stored area is returned

Alternative flow
* size is zero -- invalid area is returned

1.6 Use Case release_data

Precondition
Node must be opened yet and close must not to be in progress

Normal flow
1. rx_unlock_data ioctl was invoked
2. foreach area do
a) corresponding APP rx_tail_ptr is set to the APP rx_head_ptr value previously stored in get_data
b) HW rx_tail_ptr is updated to the min(APP rx_tail_ptrs > HW rx_tail_ptr), if there is no such value, then use min(APP rx_tail_ptrs) of corresponding area pointers. This is needed to catch pointers actually higher than others, but still belonging to the slowest readers (head usually wraps around and continues from the entry number 0).

1.7 Use Case request_space

Precondition
Node must be opened yet and close must not to be in progress.
Application must have this area subscribed for tx.
TX for requested area is not in progress (only one writer at a time).

Normal flow
1. request_space ioctl is called with size and area parameters
2. size is computed as min(max_tx_request_count, requested size, tx_ring_buffer_size - difference(HW tx_head_ptr, HW tx_tail ptr))
3. the size and HW tx_head_ptr as offset is stored into APP status_page

1.8 Use Case put_data

Precondition
Node must be opened yet and close must not to be in progress.
request_space was called by this application for area in parameter.

Normal flow
1. put_data ioctl is invoked with filled size and area where the data was filled to
2. min(size computed in request_space, supplied size) is added to the HW.tx_head_ptr

1.9 Use Case close_node

Precondition
open_node was invoked before this call

Normal flow
1. stop ioctl was called
2. node is unmap-ed
3. module's close function is called
4. if (refcount will be 0)
a) the device is stopped (it's waited for dma transfers to be aborted/finished)
b) if (allocation on modprobe) then null HW ptrs else call dealloc_rings
5. per application descriptor is deallocated

1.10 Use Case interrupt

Precondition
Hardware was started and expected to run (i.e. refcount > 0)

Normal flow
1. interrupt (timeout or ring buffer pointer reached) is raised -- ring buffer is in state we requested
2. wake applications, which are waiting for this info up

Alternative flow
* missed interrupt -- set up timer (watchdog) to cope with this

1.11 Use Case insert_module

1. modprobe/insmod the module is invoked
2. if (allocate on modpobe) then call alloc_rings

Note: 'allocate on modpobe' is set to true by default, but might be overriden by module parameter at insertion time

1.12 Use Case remove_module

1. rmmod the module is called
2. if (allocate on modpobe) then call dealloc_rings

1.13 Use Case alloc_rings

1. alloc_ring is called
2. pages for the ring buffer are allocated, each interface has its own area in the buffer (each interface has its own DMA controller and a ring buffer)
3. physical addresses are put to the hardware page pointers list -- the last descriptor points to the first

1.14 Use Case dealloc_rings

1. all ring buffer (dma) mappings and buffers are unmapped and deallocated

RX_SQD



TX_SQD