Skip to content
  • Henrique de Moraes Holschuh's avatar
    rfkill: add master_switch_mode and EPO lock to rfkill and rfkill-input · d003922d
    Henrique de Moraes Holschuh authored
    
    
    Add of software-based sanity to rfkill and rfkill-input so that it can
    reproduce what hardware-based EPO switches do, blocking all transmitters
    and locking down any further attempts to unblock them until the switch is
    deactivated.
    
    rfkill-input is responsible for issuing the EPO control requests, like
    before.
    
    While an rfkill EPO is active, all transmitters are locked to one of the
    BLOCKED states and all attempts to change that through the rfkill API
    (userspace and kernel) will be either ignored or return -EPERM errors.
    
    The lock will be released upon receipt of EV_SW SW_RFKILL_ALL ON by
    rfkill-input, or should modular rfkill-input be unloaded.
    
    This makes rfkill and rfkill-input extend the operation of an existing
    wireless master kill switch to all wireless devices in the system, even
    those that are not under hardware or firmware control.
    
    Since the above is the expected operational behavior for the master rfkill
    switch, the EPO lock functionality is not optional.
    
    Also, extend rfkill-input to allow for three different behaviors when it
    receives an EV_SW SW_RFKILL_ALL ON input event.  The user can set which
    behavior he wants through the master_switch_mode parameter:
    
    master_switch_mode = 0: EV_SW SW_RFKILL_ALL ON just unlocks rfkill
    controller state changes (so that the rfkill userspace and kernel APIs can
    now be used to change rfkill controller states again), but doesn't change
    any of their states (so they will all remain blocked).  This is the safest
    mode of operation, as it requires explicit operator action to re-enable a
    transmitter.
    
    master_switch_mode = 1: EV_SW SW_RFKILL_ALL ON causes rfkill-input to
    attempt to restore the system to the state before the last EV_SW
    SW_RFKILL_ALL OFF event, or to the default global states if no EV_SW
    SW_RFKILL_ALL OFF ever happened.   This is the recommended mode of
    operation for laptops.
    
    master_switch_mode = 2: tries to unblock all rfkill controllers (i.e.
    enable all transmitters) when an EV_SW SW_RFKILL_ALL ON event is received.
    This is the default mode of operation, as it mimics the previous behavior
    of rfkill-input.
    
    In order to implement these features in a clean way, the entire event
    handling of rfkill-input was refactored into a single worker function.
    
    Protection against input event DoS (repeatedly firing rfkill events for
    rfkill-input to process) was removed during the code refactoring.  It will
    be added back in a future patch.
    
    Note that with these changes, rfkill-input doesn't need to explicitly
    handle any radio types for which KEY_<radio type> or SW_<radio type> events
    do not exist yet.
    
    Code to handle EV_SW SW_{WLAN,WWAN,BLUETOOTH,WIMAX,...} was added as it
    might be needed in the future (and its implementation is not that obvious),
    but is currently #ifdef'd out to avoid wasting resources.
    
    Signed-off-by: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
    Cc: Ivo van Doorn <IvDoorn@gmail.com>
    Cc: Dmitry Torokhov <dtor@mail.ru>
    Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
    d003922d