/* * Translate from rfkill state to wimax state * * NOTE: Special state handling rules here * * Just pretend the call didn't happen if we are in a state where * we know for sure it cannot be handled (WIMAX_ST_DOWN or * __WIMAX_ST_QUIESCING). rfkill() needs it to register and * unregister, as it will run this path. * * NOTE: This call will block until the operation is completed. */ static int wimax_rfkill_set_radio_block(void *data, bool blocked) { int result; struct wimax_dev *wimax_dev = data; struct device *dev = wimax_dev_to_dev(wimax_dev); enum wimax_rf_state rf_state; d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked); rf_state = WIMAX_RF_ON; if (blocked) rf_state = WIMAX_RF_OFF; mutex_lock(&wimax_dev->mutex); if (wimax_dev->state <= __WIMAX_ST_QUIESCING) result = 0; else result = __wimax_rf_toggle_radio(wimax_dev, rf_state); mutex_unlock(&wimax_dev->mutex); d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n", wimax_dev, blocked, result); return result; }
/** * wimax_rfkill - Set the software RF switch state for a WiMAX device * * @wimax_dev: WiMAX device descriptor * * @state: New RF state. * * Returns: * * >= 0 toggle state if ok, < 0 errno code on error. The toggle state * is returned as a bitmap, bit 0 being the hardware RF state, bit 1 * the software RF state. * * 0 means disabled (%WIMAX_RF_ON, radio on), 1 means enabled radio * off (%WIMAX_RF_OFF). * * Description: * * Called by the user when he wants to request the WiMAX radio to be * switched on (%WIMAX_RF_ON) or off (%WIMAX_RF_OFF). With * %WIMAX_RF_QUERY, just the current state is returned. * * NOTE: * * This call will block until the operation is complete. */ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state) { int result; struct device *dev = wimax_dev_to_dev(wimax_dev); d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); if (result < 0) { /* While initializing, < 1.4.3 wimax-tools versions use * this call to check if the device is a valid WiMAX * device; so we allow it to proceed always, * considering the radios are all off. */ if (result == -ENOMEDIUM && state == WIMAX_RF_QUERY) result = WIMAX_RF_OFF << 1 | WIMAX_RF_OFF; goto error_not_ready; } switch (state) { case WIMAX_RF_ON: case WIMAX_RF_OFF: result = __wimax_rf_toggle_radio(wimax_dev, state); if (result < 0) goto error; rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); break; case WIMAX_RF_QUERY: break; default: result = -EINVAL; goto error; } result = wimax_dev->rf_sw << 1 | wimax_dev->rf_hw; error: error_not_ready: mutex_unlock(&wimax_dev->mutex); d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", wimax_dev, state, result); return result; }
int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state) { int result; struct device *dev = wimax_dev_to_dev(wimax_dev); d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); mutex_lock(&wimax_dev->mutex); result = wimax_dev_is_ready(wimax_dev); if (result < 0) { /* */ if (result == -ENOMEDIUM && state == WIMAX_RF_QUERY) result = WIMAX_RF_OFF << 1 | WIMAX_RF_OFF; goto error_not_ready; } switch (state) { case WIMAX_RF_ON: case WIMAX_RF_OFF: result = __wimax_rf_toggle_radio(wimax_dev, state); if (result < 0) goto error; rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); break; case WIMAX_RF_QUERY: break; default: result = -EINVAL; goto error; } result = wimax_dev->rf_sw << 1 | wimax_dev->rf_hw; error: error_not_ready: mutex_unlock(&wimax_dev->mutex); d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", wimax_dev, state, result); return result; }