static ssize_t write_file_ani(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long ani; char buf[32]; ssize_t len; len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; if (kstrtoul(buf, 0, &ani)) return -EINVAL; if (ani > 1) return -EINVAL; common->disable_ani = !ani; if (common->disable_ani) { clear_bit(ATH_OP_ANI_RUN, &common->op_flags); ath_stop_ani(sc); } else { ath_check_ani(sc); } return count; }
void ath_check_ani(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon; /* * Check for the various conditions in which ANI has to * be stopped. */ if (ah->opmode == NL80211_IFTYPE_ADHOC) { if (!cur_conf->enable_beacon) goto stop_ani; } else if (ah->opmode == NL80211_IFTYPE_AP) { if (!cur_conf->enable_beacon) { /* * Disable ANI only when there are no * associated stations. */ if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) goto stop_ani; } } else if (ah->opmode == NL80211_IFTYPE_STATION) { if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) goto stop_ani; } if (!test_bit(ATH_OP_ANI_RUN, &common->op_flags)) { set_bit(ATH_OP_ANI_RUN, &common->op_flags); ath_start_ani(sc); } return; stop_ani: clear_bit(ATH_OP_ANI_RUN, &common->op_flags); ath_stop_ani(sc); }