/** * wimax_dev_rm - Unregister an existing WiMAX device * * @wimax_dev: WiMAX device descriptor * * Unregisters a WiMAX device previously registered for use with * wimax_add_rm(). * * IMPORTANT! Must call before calling unregister_netdev(). * * After this function returns, you will not get any more user space * control requests (via netlink or debugfs) and thus to wimax_dev->ops. * * Reentrancy control is ensured by setting the state to * %__WIMAX_ST_QUIESCING. rfkill operations coming through * wimax_*rfkill*() will be stopped by the quiescing state; ops coming * from the rfkill subsystem will be stopped by the support being * removed by wimax_rfkill_rm(). */ void wimax_dev_rm(struct wimax_dev *wimax_dev) { d_fnstart(3, NULL, "(wimax_dev %p)\n", wimax_dev); mutex_lock(&wimax_dev->mutex); __wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); wimax_debugfs_rm(wimax_dev); wimax_id_table_rm(wimax_dev); __wimax_state_change(wimax_dev, WIMAX_ST_DOWN); mutex_unlock(&wimax_dev->mutex); wimax_rfkill_rm(wimax_dev); d_fnend(3, NULL, "(wimax_dev %p) = void\n", wimax_dev); }
/** * wimax_state_change - Set the current state of a WiMAX device * * @wimax_dev: WiMAX device descriptor (properly referenced) * @new_state: New state to switch to * * This implements the state changes for the wimax devices. It will * * - verify that the state transition is legal (for now it'll just * print a warning if not) according to the table in * linux/wimax.h's documentation for 'enum wimax_st'. * * - perform the actions needed for leaving the current state and * whichever are needed for entering the new state. * * - issue a report to user space indicating the new state (and an * optional payload with information about the new state). * * NOTE: @wimax_dev must be locked */ void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state) { mutex_lock(&wimax_dev->mutex); __wimax_state_change(wimax_dev, new_state); mutex_unlock(&wimax_dev->mutex); return; }
/** * wimax_report_rfkill_hw - Reports changes in the hardware RF switch * * @wimax_dev: WiMAX device descriptor * * @state: New state of the RF Kill switch. %WIMAX_RF_ON radio on, * %WIMAX_RF_OFF radio off. * * When the device detects a change in the state of thehardware RF * switch, it must call this function to let the WiMAX kernel stack * know that the state has changed so it can be properly propagated. * * The WiMAX stack caches the state (the driver doesn't need to). As * well, as the change is propagated it will come back as a request to * change the software state to mirror the hardware state. * * If the device doesn't have a hardware kill switch, just report * it on initialization as always on (%WIMAX_RF_ON, radio on). */ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, enum wimax_rf_state state) { int result; struct device *dev = wimax_dev_to_dev(wimax_dev); enum wimax_st wimax_state; d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); BUG_ON(state == WIMAX_RF_QUERY); BUG_ON(state != WIMAX_RF_ON && state != WIMAX_RF_OFF); mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); if (result < 0) goto error_not_ready; if (state != wimax_dev->rf_hw) { wimax_dev->rf_hw = state; if (wimax_dev->rf_hw == WIMAX_RF_ON && wimax_dev->rf_sw == WIMAX_RF_ON) wimax_state = WIMAX_ST_READY; else wimax_state = WIMAX_ST_RADIO_OFF; result = rfkill_set_hw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); __wimax_state_change(wimax_dev, wimax_state); } error_not_ready: mutex_unlock(&wimax_dev->mutex); d_fnend(3, dev, "(wimax_dev %p state %u) = void [%d]\n", wimax_dev, state, result); }
/* * Callback for the RF Kill toggle operation * * This function is called by: * * - The rfkill subsystem when the RF-Kill key is pressed in the * hardware and the driver notifies through * wimax_report_rfkill_hw(). The rfkill subsystem ends up calling back * here so the software RF Kill switch state is changed to reflect * the hardware switch state. * * - When the user sets the state through sysfs' rfkill/state file * * - When the user calls wimax_rfkill(). * * This call blocks! * * WARNING! When we call rfkill_unregister(), this will be called with * state 0! * * WARNING: wimax_dev must be locked */ static int __wimax_rf_toggle_radio(struct wimax_dev *wimax_dev, enum wimax_rf_state state) { int result = 0; struct device *dev = wimax_dev_to_dev(wimax_dev); enum wimax_st wimax_state; might_sleep(); d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); if (wimax_dev->rf_sw == state) goto out_no_change; if (wimax_dev->op_rfkill_sw_toggle != NULL) result = wimax_dev->op_rfkill_sw_toggle(wimax_dev, state); else if (state == WIMAX_RF_OFF) /* No op? can't turn off */ result = -ENXIO; else /* No op? can turn on */ result = 0; /* should never happen tho */ if (result >= 0) { result = 0; wimax_dev->rf_sw = state; wimax_state = state == WIMAX_RF_ON ? WIMAX_ST_READY : WIMAX_ST_RADIO_OFF; __wimax_state_change(wimax_dev, wimax_state); } out_no_change: d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", wimax_dev, state, result); return result; }
void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state) { mutex_lock(&wimax_dev->mutex); if (wimax_dev->state > __WIMAX_ST_NULL) __wimax_state_change(wimax_dev, new_state); mutex_unlock(&wimax_dev->mutex); return; }
/** * wimax_state_change - Set the current state of a WiMAX device * * @wimax_dev: WiMAX device descriptor (properly referenced) * @new_state: New state to switch to * * This implements the state changes for the wimax devices. It will * * - verify that the state transition is legal (for now it'll just * print a warning if not) according to the table in * linux/wimax.h's documentation for 'enum wimax_st'. * * - perform the actions needed for leaving the current state and * whichever are needed for entering the new state. * * - issue a report to user space indicating the new state (and an * optional payload with information about the new state). * * NOTE: @wimax_dev must be locked */ void wimax_state_change(struct wimax_dev *wimax_dev, enum wimax_st new_state) { /* * A driver cannot take the wimax_dev out of the * __WIMAX_ST_NULL state unless by calling wimax_dev_add(). If * the wimax_dev's state is still NULL, we ignore any request * to change its state because it means it hasn't been yet * registered. * * There is no need to complain about it, as routines that * call this might be shared from different code paths that * are called before or after wimax_dev_add() has done its * job. */ mutex_lock(&wimax_dev->mutex); if (wimax_dev->state > __WIMAX_ST_NULL) __wimax_state_change(wimax_dev, new_state); mutex_unlock(&wimax_dev->mutex); }