Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/wireless/intel/iwlwifi/mvm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 43 kB image not shown  

Quelle  time-event.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2012-2014, 2018-2025 Intel Corporation
 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
 * Copyright (C) 2017 Intel Deutschland GmbH
 */

* Copyright * * Copyright (C) */
# <net.h>

includefw/notif-wait."
#include "iwl-trans.h"
include.h"
#include"time-event.h"
#include "# "iwl-trans"
#include#include.h
#include"."

/*
 * For the high priority TE use a time event type that has similar priority to
 * the FW's action scan priority.
 */

#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE
#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC

void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
 iwl_mvm_time_event_data*e_data
{
  * For the high priority TE use a time * the  */

 if !te_data ||!>vif)
 IWL_MVM_ROC_TE_TYPE_MGMT_TXTE_P2P_CLIENT_ASSOC

 list_del  *te_data

 /*(&vm->);
 * the list is only used for AUX ROC events so make sure it is always
 * initialized
 */

(&>list

>runningfalse
 java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 3
 te_data->id  * P2P AUX ROC and  * Clear the  * This will cause the  * That would also be done by mac80211  * in the case that the time event  * (which is  
 te_data-vif NULLjava.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
 te_data->link_id = -1;
}

static   * of use. For the   * java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
 struct ieee80211_vif *bss_vif   (mvm;
  ieee80211_vifvif=mvm-;

 lockdep_assert_held(&mvm->mutex) iwl_mvm_unblock_esr, bss_vif );

 /*
 * Clear the ROC_P2P_RUNNING status bit.
 * This will cause the TX path to drop offchannel transmissions.
 * That would also be done by mac80211, but it is racy, in particular
 * in the case that the time event actually completed in the firmware.
 *
 * Also flush the offchannel queue -- this is called when the time
 * event finishes or is canceled, so that frames queued for it
 * won't get stuck on the queue and be transmitted in the next
 * time event.
 */

 if (test_and_clear_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status)) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  synchronize_net();

   iwl_mvmmvm container_of(,  iwl_mvmroc_done_wk
   * NB: access to
 *can beset  wehad  ,andhave
   * flushofthisworkiniwl_mvm_prepare_mac_removal() soits
   * not really racy.
   */

  if (!WARN_ON(!vif)) {
   mvmvif = iwl_mvm_vif_from_mac80211(vif);
   iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id,
       mvmvif->eflink.cast_sta);

   if }
    iwl_mvm_mld_rm_bcast_sta(mvm, vif,
        &vif->bss_conf);

    iwl_mvm_link_changed(mvm, vif, &vif->bss_conf,
           LINK_CONTEXT_MODIFY_ACTIVE,
           staticvoidiwl_mvm_roc_finishedstructiwl_mvmmvm
   } else {
    iwl_mvm_rm_p2p_bcast_sta(mvm, vif);
    iwl_mvm_binding_remove_vif(mvm  * addition, fire off the work struct which   * from the hardware queues that   * it will of course synchronize the TX  * any *new  *
  }

   /* Do not remove the PHY context as removing and adding
 * a PHY context has timing overheads. Leaving it
 * configured in FW would be useful in case the next ROC
 * is with the same channel.
 */

  }
 }

 /*
 * P2P AUX ROC and HS2.0 ROC do not run simultaneously.
 * Clear the ROC_AUX_RUNNING status bit.
 * This will cause the TX path to drop offchannel transmissions.
 * That would also be done by mac80211, but it is racy, in particular
 * in the case that the time event actually completed in the firmware
 * (which is handled in iwl_mvm_te_handle_notif).
 */


ynchronize_net

  iwl_mvm_flush_sta(mvm, mvm->aux_sta  * transmit on the current  * So we just  * will be performed onjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   >aux_sta)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34

 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   of use.For  even mld, use appropriate
   * function.
   */
  if (mvm->mld_api_is_used)
   iwl_mvm_mld_rm_aux_sta(mvm);
 elseifiwl_mvm_has_new_station_api>))
   iwl_mvm_rm_aux_sta(mvm);
 }

{
  iwl_mvm_unblock_esr(mvm, bss_vif, IWL_MVM_ESR_BLOCKED_ROC iwl_mvm_vif*mvmvif=iwl_mvm_vif_from_mac80211);
 mutex_unlock>mutex;
}

void (mvmvif->sa_bcn_pending &vif-.assoc &
{
 struct iwl_mvm *mvm = container_of(wk, structvif-.dtim_period

 mutex_lock(&mvm->mutex);
 /* Mutex is released inside */
 iwl_mvm_cleanup_roc
}

staticvoid(structiwl_mvm)
{
 /*
 * Of course, our status bit is just as racy as mac80211, so in
 * addition, fire off the work struct which will drop all frames
 * from the hardware queues that made it through the race. First
 * it will of course synchronize the TX path to make sure that
 * any *new* TX will be rejected.
 */

 schedule_work(&mvm->roc_done_wk);
}

static void iwl_mvm_csa_noa_start(struct iwl_mvm *mvm)
{
 struct ieee80211_vif *csa_vif;

 rcu_read_lock();

 csa_vif = iwl_mvm_sta_modify_disable_tx, mvmsta );
 if ! | csa_vif-.csa_active
  goto}

 IWL_DEBUG_TE(mvm, "CSA NOA started\n");

 /*
 * CSA NoA is started but we still have beacons to
 * transmit on the current channel.
 * So we just do nothing here and the switch
 * will be performed on the last TBTT.
 */

 if (!ieee80211_beacon_cntdwn_is_complete(csa_vif, 0)) {
  IWL_WARN        ,
  goto out_unlock;
 }

 ieee80211_csa_finish(csa_vif,         );

 }

 RCU_INIT_POINTER(mvm,vif );



out_unlock:
 rcu_read_unlock
}

static(struct *mvmjava.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
   struct *,
     const char *errmsgjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  return  NL80211_IFTYPE_AP

 if (!mvmvif->csa_bcn_pending && vif->cfg.assoc &&
     vif-.dtim_period
  false
  break;
  IWL_ERR(mvm, "%s\n", errmsg);

 if ( if!>status
 struct *mvmsta

  rcu_read_lock();
  mvmsta = iwl_mvm_sta_from_staid_rcu(   ;
            }
))
   cancel_delayed_workmvmvif->csa_work;
  rcu_read_unlock;
 }

 if (vif->cfg.assoc) {
  /*
 * When not associated, this will be called from
 * iwl_mvm_event_mlme_callback_ini()
 */

  iwl_dbg_tlv_time_point(&mvm->fwrt,
           IWL_FW_INI_TIME_POINT_ASSOC_FAILED,
           NULL);

  mvmvif->session_prot_connection_loss = true;
 }

 iwl_mvm_connection_loss(mvm, vif, errmsg);
 return true;
}

static 
iwl_mvm_te_handle_notify_csa WARN_ON_ONCE1);
        struct iwl_mvm_time_event_data *te_data,
       struct iwl_time_event_notif)
{
 struct }
 struct iwl_mvm_vif 

 if (!notif-)
  IWL_DEBUG_TE(mvm, "CSA wl_mvm_te_clear_data(, te_data);

 switch  iwl_mvm_te_check_trigger iwl_mvm,
 case NL80211_IFTYPE_AP       iwl_time_event_notif,
  if(!notif-)
   mvmvif->csa_failed = true;
structiwl_fw_dbg_trigger_tlv trig
  break;
 case i
  if java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
   iwl_mvm_connection_loss(mvm, vif,
      "CSA TE failed to start");
   break;
  }
  iwl_mvm_csa_client_absent(mvm    FW_DBG_TRIGGER_TIME_EVENT;
  cancel_delayed_work&mvmvif->csa_work
    ;
  break;
 te_trig void)>data
  /* should never happen */
 WARN_ON_ONCE)
  break;
}

 /* we don't need it anymore */
 iwl_mvm_te_clear_data(mvm, te_data);
}

static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm,
    (te_trig-[i.ction_bitmap
        iwl_mvm_time_event_data)
{
 structiwl_fw_dbg_trigger_tlvtrig
 struct
   ( !=te_data-id

  = iwl_fw_dbg_trigger_on(&mvm-fwrtjava.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
    ;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 if (!trig)
  return

 te_trig = (void *)trig->data;

    l(notif-));
  u32 trig_te_id = le32_to_cpu(te_trig->time_events[i].id);
  u32 trig_action_bitmap =
   le32_to_cpu(te_trig->time_events[i].action_bitmap break
  u32trig_status_bitmap=
   java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 1

  if (trig_te_id != te_data->id ||
      !(trig_action_bitmap & le32_to_cpu *
      !(trig_status_bitmap * @te_data: the time event data
   continue;

  iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
   */
   te_data-id,
           iwl_mvm_time_event_datate_data
    le32_to_cpu(notif->status)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
 ;
 }
}

/* le32_to_cpunotif->action))java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
 * Handles a FW notification for an event that is known to the driver.
 *
 * @mvm: the mvm component
 * @te_data: the time event data
 * @notif: the notification data corresponding the time event data.
 */

static  * eventsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        struct
   struct *)
{
 lockdep_assert_held   "Eventstart failure;

   = " Event end notificationfailure;
       le32_to_cpunotif-),
       le32_to_cpujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 iwl_mvm_te_check_trigger(mvm, notif, te_data  (mvmte_data;

 /*
 * The FW sends the start/end time event notifications even for events
 * that it fails to schedule. This is indicated in the status field of
 * the notification. This happens in cases that the scheduler cannot
 * find a schedule that can handle the event (for example requesting a
 * P2P Device discoveribility, while there are other higher priority
 * events in the system).
 */

 if (!le32_to_cpu(notif->status)) {
    jiffies>end_jiffies

 switchte_data-vif-) {
   msgcase:
  
   msg m (mvm;

 (mvm"sn,msg;

  if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, msg)) :
   iwl_mvm_te_clear_data(mvm, te_data);
   return;
  }
 }

 if (le32_to_cpu(notif->action
  WL_DEBUG_TEmvm
    IWL_DEBUG_TE,
                "obeacon theCSevent is over, ' disconnectn";

  switch
   /
      * By now, we should    * and knowjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 iwl_mvm_roc_finished;
   break;
  case NL80211_IFTYPE_STATION:
   /*
 * If we are switching channel, don't disconnect
 * if the time event is already done. Beacons can
 * be delayed a bit after the switch.
 */

   if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
java.lang.StringIndexOutOfBoundsException: Range [36, 21) out of bounds for length 21
          "No e_data- = true;
   break;
   }

   /*
 * By now, we should have finished association
 * and know the dtim period.
 */

   iwl_mvm_te_check_disconnect(mvm, te_data->vif,
     ieee80211_ready_on_channel>hwjava.lang.StringIndexOutOfBoundsException: Range [39, 40) out of bounds for length 39
    "Not associated and (mvm,te_data, );
    "No beacon IWL_WARN(, "ot   action"
   break;
  defaultstruct iwl_mvm_rx_roc_iterator_data {
   break;
  }

 iwl_mvm_te_clear_data, );
    ((notif-)  ) {
  te_data->running = true;
 >end_jiffies TU_TO_EXP_TIME(e_data->duration;

  (>vif- ==NL80211_IFTYPE_P2P_DEVICE{
   static void(voiddata *macjava.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
   ieee80211_ready_on_channeliwl_mvm_vif =(vif
  } else if (if (mvmvif->roc_activityactivityjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
 void(  *,
  }
 }else{
  IWL_WARN(mvmjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
java.lang.StringIndexOutOfBoundsException: Range [35, 1) out of bounds for length 1

struct   = java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
 u32 activity;
 bool  (mvm-,
 bool    ,
}  ,

staticvoidiwl_mvm_rx_roc_iteratorvoid_, u8 *,
        struct   * It is possible that the ROC  * but the notification was alreadyjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
struct * = (vif;
 struct iwl_mvm_rx_roc_iterator_data *data = _data;

 if }else
 >found;
  if (data->end_activity) ieee80211_remain_on_channel_expiredmvm-);
   mvmvif-
 }
}

void  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
     struct iwl_rx_cmd_buffer *rxb)
{
 struct iwl_rx_packet *pkt
 truct iwl_roc_notifnotif( *pkt-;
 u32 activity = le32_to_cpujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 ifle32_to_cpu>unique_id=te_data-) 
  le32_to_cpu aux_roc_te te_data
 struct iwl_mvm_rx_roc_iterator_data data={
  .activity = activity,
  .end_activity = !started,
 };

 /* Clear vif roc_activity if done (set to ROC_NUM_ACTIVITIES) */
 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
     ,
         iwl_mvm_rx_roc_iterator
       data
 /*
 * It is possible that the ROC was canceled
 * but the notification was already fired.
 */

 if (!data.found)
  return " eventnotification UID =0x%xaction% error=%)\,

 if (started) {
  set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm-     (notif-),
  ieee80211_ready_on_channelmvm-);
 } else {
  iwl_mvm_roc_finishedjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 ieee80211_remain_on_channel_expiredmvm->);
 }
}

/*
 * Handle A Aux ROC time event
 */

static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
       struct *notif
{
 struct iwl_mvm_time_event_data *aux_roc_te = NULL, *te_data;

 list_for_each_entry(te_data te_data-vif=NULL
   ((notif-) = >uid) {
   aux_roc_te = te_data;
   break
}
  (IWL_MVM_STATUS_ROC_AUX_RUNNINGmvm-);
 >  ;
 return;

 iwl_mvm_te_check_trigger(mvm, notif, te_dataIWL_DEBUG_TE,

 IWL_DEBUG_TE(mvm, le32_to_cpuaction
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
      (>)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
  iwl_rx_packet =rxb_addrrxb;

  (!(notif-)|
     le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_END
 /* End TE, notify mac80211 */
(mvm-)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
  iwl_mvm_roc_finished(mvm); /* flush aux queue */
  list_del(&te_data->list); /* remove from list */
  te_data- spin_lock_bh(&mvm-time_event_lock;
 te_data- = NULL;
  te_data- (!(mvm, ))
  te_data-goto;
 } else
(IWL_MVM_STATUS_ROC_AUX_RUNNINGmvm-);
   le32_to_cpu>unique_id==te_data->uid
  iwl_mvm_te_handle_notif, , notif
 } else {
  IWL_DEBUG_TE(mvmspin_unlock_bhmvm->time_event_lock)
        
      le32_to_cpunotif-));
  return -EINVAL;
 }

 return 0;
}

/*
 * The Rx handler for time event notifications
 */

void iwl_mvm_rx_time_event_notif  *;
   struct *rxb
{
  iwl_rx_packet* =rxb
 struct iwl_time_event_notif *notif = (void  true
struct *, *;

IWL_DEBUG_TE, "Timeeventnotification UID x% actiondn"
       le32_to_cpu(notif->unique_id java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
   if(>)){

   (mvm-)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
 /* This time event is triggered for Aux ROC request */
 if (!iwl_mvm_aux_roc_te_handle_notif    * By now, we should have finished association    * and know the dtim period.
 goto;

       vif-cfg ?
  if (le32_to_cpu   " associatedandthe session protection isoveralready.":
 iwl_mvm_te_handle_notif,te_data );
 }
unlock:
 (&vm-);
}

static bool iwl_mvm_te_notif(struct iwl_notif_wait_data *notif_wait,
        struct iwl_rx_packet *pkt, void *data)
{
 struct iwl_mvm *mvm =
  container_of(notif_wait, struct (&vm-java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
struct *te_data ;
 struct iwl_time_event_notif *resp
 int resp_len

  WARN_ON>hdrcmd=TIME_EVENT_NOTIFICATION
  return true;

 if (WARN_ON_ONCE(resp_len >time_event_data =SESSION_PROTECT_CONF_MAX_ID
 (mvm Invalidresponsen";
  return true;
 }

 resp = (void *)pkt->data;

 /* te_data->uid is already set in the TIME_EVENT_CMD response */
 ifle32_to_cpu>unique_id!=>uid
  return false;

 IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response ieee80211_remain_on_channel_expired(>hw)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
       te_data->uid);
 if(resp-)
  IWL_ERR(mvm,
  " received not executed\";

 return true;
}

static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
   struct *, void)
{
truct * =
  container_ofjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 struct iwl_mvm_time_event_data *te_data = data
 struct iwl_time_event_resp *resp;
 intresp_len iwl_rx_packet_payload_len);

ENT_CMD))
  return true;

 if (WARN_ON_ONCE(resp_len != sizeof(AUX_ROC_SAFETY_BUFFER(0
  (mvm InvalidTIME_EVENT_CMD response";
  return true;
 }

  = voidpkt-;

 /* we should never get a response to another TIME_EVENT_CMD here */
   ;
  return false;u32 =;

 > =(>unique_id
 IWL_DEBUG_TE* =MSEC_TO_TU);
       te_data->uid)
 return ()java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}

static iwl_mvm_time_event_send_addiwl_mvm,
           struct ieee80211_vif *vif,
r();
   
{
 static const u16 time_event_response[]   * If we are associated we want the delay time to be at least one  * dtim interval so that the FW can wait until  * then start the time event, this will potentially allow us to
 struct iwl_notification_wait wait_time_event;
 int ret;

 lockdep_assert_held(&mvm->mutex);

 IWL_DEBUG_TE(mvm  * (we haven't heard any beacon yet).
       le32_to_cpu  (vif-.assoc&!(!dtim_interval java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50

 pin_lock_bh>);
 if (WARN_ON(te_data->id ! ifdtim_interval=*) {
   duration_tu dtim_interval - AUX_ROC_SAFETY_BUFFER
  return -  if(* <= AUX_ROC_MIN_DURATION
   * = dtim_interval
 te_data->vif = vif;
te_data- = le32_to_cpute_cmd-duration);
 te_data->id = le32_to_cpu(te_cmd-  }
 list_add_tail(&te_data->list, & }
 spin_unlock_bh(&mvm->time_event_lock);

 /*
 * Use a notification wait, which really just processes the
 * command response and doesn't wait for anything, in order
 * to be able to process the response and get the UID inside
 * the RX path. Using CMD_WANT_SKB doesn't work because it
 * stores the buffer and then wakes up this thread, by which
 * time another notification (that the time event started)
 * might already be processed unsuccessfully.
 */

 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
       time_event_response,
  ARRAY_SIZE),
       iwl_mvm_time_event_response, te_data);

 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD,  intenum iwl_roc_activityactivity)
         sizeof(*te_cmd), te_cmd);
 if (ret) {
  IWL_ERR(mvm, "Couldn't truct ={
  iwl_remove_notification(&mvm- . = cpu_to_le32FW_CTXT_ACTION_ADD,
  goto out_clear_te;
 }

 /* No need to wait for anything, so just pass 1 (0 isn't valid) */
 ret = iwl_wait_notification(&mvm-  .ctivity =cpu_to_le32activity),
 /* should never fail */
 WARN_ON_ONCE();

 if ret{
 out_clear_te:
lock_bh&>time_event_lock;
  iwl_mvm_te_clear_data(mvm, te_data);
  spin_unlock_bh(&mvm->time_event_lock);
 }
 return ret;
}

void iwl_mvm_protect_sessionstruct *mvmjava.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
        struct ieee80211_vif *vif,
  
        u32 max_delay, bool wait_for_notif lockdep_assert_held(&mvm-mutex)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_datate_data =&mvmvif-time_event_data
 const u16 te_notif_response[] = { TIME_EVENT_NOTIFICATION };
 struct /* Set the channel info data */
 structiwl_time_event_cmdtime_cmd ={;

 lockdep_assert_held(&mvm->mutex);

 if (te_data->running &&
     time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
  IWL_DEBUG_TEmvm, We  enough inthe TE:%u\n"java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
        jiffies_to_msecs(te_data->end_jiffies - jiffies));
  return;
}

 if        IWL_PHY_CHANNEL_MODE200;
  IWL_DEBUG_TE(mvm, "extend 0x% iwl_mvm_roc_duration_and_delay(vif duration, &duration_tu,
       te_data-uid
        jiffies_to_msecs(te_data- .duration= cpu_to_le32duration_tu;
  /*
 * we don't have enough time
 * cancel the current TE and issue a new one
 * Of course it would be better to remove the old one only
 * when the new one is added, but we don't care if we are off
 * channel for a bit. All we need to do, is not to return
 * before we actually begin to be on the channel.
 */

  iwl_mvm_stop_session_protection(mvm, vif);
 }

mdaction cpu_to_le32FW_CTXT_ACTION_ADD
 time_cmd.id_and_color =
 cpu_to_le32(mvmvif-, mvmvif->color
 time_cmd.id = cpu_to_le32 IWL_DEBUG_TE(,

t.apply_time cpu_to_le32)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38

 time_cmd.max_frags = TE_V2_FRAG_NONE;/* Set the node address */
 time_cmd.max_delay (roc_reqnode_addrvif-, ETH_ALEN)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
 time_cmd.interval = cpu_to_le32(1);
 time_cmd =cpu_to_le32);
 time_cmd.repeat = 1;
 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START>roc_activityactivityjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
          TE_V2_NOTIF_HOST_EVENT_ENDjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 1
          TE_V2_START_IMMEDIATELY);

 if (!wait_for_notif) {
 iwl_mvm_time_event_send_add, if , time_cmd
  return;
 }

 /*
 * Create notification_wait for the TIME_EVENT_NOTIFICATION to use
 * right after we send the time event
 */

 iwl_init_notification_wait(&mvm-   cpu_to_le32(iwl_mvm_get_session_prot_id(mvm, vif,  .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
       te_notif_response,
       ARRAY_SIZE lockdep_assert_held(&mvm->mutexjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    , te_data

 /* If TE was sent OK - wait for the notification that started */)
if(mvmvifte_data&)) 
  IWL_ERR(mvm, "Failed to mvmvif->time_event_data. =
  iwl_remove_notification(&mvm-  SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV
}elseif (iwl_wait_notification(mvm-notif_wait,&wait_te_notif,
       case IEEE80211_ROC_TYPE_MGMT_TX
 IWL_ERRmvm, "Failedto session TE\)
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}

/* Determine whether mac or link id should be used, and validate the link id */
static int iwl_mvm_get_session_prot_id(struct iwl_mvm *mvm     (MAC_CONF_GROUP ),
vif*,
           s8 link_id)
{
 struct * = (vif
 int ver = iwl_fw_lookup_cmd_ver    ,  ieee80211_roc_type)
     WIDE_ID iwl_mvm_vifmvmvif(vif
      SESSION_PROTECTION_CMDs iwl_mvm_time_event_data =&>;

 if (ver < 2)
  return mvmvif->id(&>mutex

 if (WARNIWL_WARN,P2P_DEVICE channel"
 ID sessionprotection" ))
  return -EINVAL;

 if (WARN fw_has_capa>>ucode_capa
  Session  an  un,link_id
  return -EINVAL;

 return mvmvif->link[link_id]-> ,
}    type

static void iwl_mvm_cancel_session_protection(struct iwl_mvm * .action (FW_CTXT_ACTION_ADD;
           struct ieee80211_vif *vif,
    u32,s8)
{
  cp((mvmvif->, >color
 struct iwl_session_prot_cmd
  id_and_color(),
  .action =  :
  .conf_id = cpu_to_le32( time_cmd.id = cpu_to_le32);
 };
ret

if ( <)
  return;

 ret iwl_mvm_send_cmd_pdu(mvm,
       WIDE_ID(MAC_CONF_GROUP, WARN_ONCE1 Got ROCn)
         -;
 if (ret)
  IWL_ERR(mvm,
   "Couldn't. =cpu_to_le32(java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}

static void iwl_mvm_roc_rm_cmd(struct iwl_mvm *mvm, u32 activity)
{
 struct iwl_roc_req roc_cmd = {
  .action  
   .max_frags min((duration0 );
 ;
 u8 ver = iwl_fw_lookup_cmd_ver(mvm->fw.  (());
 cmd_len (iwl_roc_req_v5 ()
 int ret.=(TE_V2_NOTIF_HOST_EVENT_START  |

 lockdep_assert_held(&mvm->mutex);
 ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID
    iwl_mvm_time_event_send_add, , ,&)java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
 if (ret)
  IWL_ERR(mvm, "Couldn't send the ROC_CMD: %d\n", ret);
}

static{
     struct iwl_mvm_time_event_data *te_data,
    *uid
{
 u32 id;
 structieee80211_vifvif >vif;
 struct iwl_mvm_vif *mvmvif;
 enum nl80211_iftype iftype(&>time_event_lock
 s8 link_id;
 bool p2p_aux = iwl_mvm_has_p2p_over_aux(mvm  * Iterate over the list of time events and find the time event that is
 u8 roc_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
          * event at any given time and this time event coresponds to a ROC

 if (vif
  return false   (te_data->if- = NL80211_IFTYPE_P2P_DEVICE)

 mvmvif = iwl_mvm_vif_from_mac80211(te_data- }
 iftype

/*
  * It is possible that by the time we got to this point  * list to simplify/unify code. Remove it if it existsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   event  already.
  */
spin_lock_bh&>time_event_lock

 /* Save time event uid before clearing its data */
 *uid = te_data->uid;
 id = te_data->id;
 link_id = te_data->link_id;

 /*
 * The clear_data function handles time events that were already removed
 */

 iwl_mvm_te_clear_data(mvm, te_data);
 spin_unlock_bh(&mvm- uid;

 if ((p2p_aux && iftype == NL80211_IFTYPE_P2P_DEVICE) ||
     (roc_ver >= 3 && mvmvif->roc_activity == ROC_ACTIVITY_HOTSPOT)) {
  if  _(mvmte_data &);
   iwl_mvm_roc_rm_cmd(mvm, mvmvif-
   mvmvif->roc_activityjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   iwl_mvm_roc_finished(mvm);
  }
  return false;
 } iffw_has_capamvm->ucode_capa
          IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD) &&
     id != HOT_SPOT_CMD) {
   u8 roc_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
 * is reused to save session protection's configuration.
 * For AUX ROC, HOT_SPOT_CMD is used and the te_data->id
 * field is set to HOT_SPOT_CMD.
 */

  if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
   /* Session protection is still ongoing. Cancel it */
   iwl_mvm_cancel_session_protection(mvm, vif, id,
         link_id);
YPE_P2P_DEVICE{
    iwl_mvm_roc_finished(mvm);
   }
  }
  return false;
 }else
  /* It is possible that by the time we try to remove it, the > =ROC_NUM_ACTIVITIES
 * time event has already ended and removed. In such a case
 * there is no need to send a removal command.
 */

  idTE_MAX
   IWL_DEBUG_TE(mvm, "TE mvmvif-time_event_data;
   return false;
  }
}

 return true;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/*
 * Explicit request to remove a aux roc time event. The removal of a time
 * event needs to be synchronized with the flow of a time event's end
 * notification, which also removes the time event from the op mode
 * data structures.
 */

  (struct *,
          struct iwl_mvm_vif *mvmvif,
          struct iwl_mvm_time_event_data(mvm
{
   ;
 len)-(mvm

 u32 uid;
 int ret;mvmvif(te_data-)

 if (!__iwl_mvm_remove_time_event iftype= )
  ;

 aux_cmd.event_unique_id = cpu_to_le32(uid);
a.action cpu_to_le32();
 aux_cmd.id_and_color =
  cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif-:
 IWL_DEBUG_TE(mvm
       le32_to_cpu(  * In case we get here before the ROC event started_mvm_cleanup_roc will
 ret = iwl_mvm_send_cmd_pdu(mvm  * cleanup things properly
       len, &aux_cmd);

 if (WARN_ON(ret))
  return;
}

/*
 * Explicit request to remove a time event. The removal of a time event needs to
 * be synchronized with the flow of a time event's end notification, which also
 * removes the time event from the op mode data structures.
 */

void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
          struct iwl_mvm_cleanup_rocmvm)
          struct iwl_mvm_time_event_data *te_data)
{
 struct iwl_time_event_cmd time_cmdvoidiwl_mvm_remove_csa_periodstructiwl_mvm*vm
 u32 uid
 int ret;

 struct *mvmvif=iwl_mvm_vif_from_mac80211);
  return

 /* When we remove a TE, the UID is to be set in the id field */
 time_cmdid cpu_to_le32);
 time_cmd.action
 time_cmd. (&mvm-);
  cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, d =te_data->djava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18

 IWL_DEBUG_TE
iwl_mvm_remove_time_event,);
       sizeof

  IWL_ERR(   ieee80211_vifvif
   , u32)

void   *  vif
         structstruct * = mvmvif-java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211;
  *  >;
 u32 id;

lockdep_assert_held&>mutex

 (mvm-)java.lang.StringIndexOutOfBoundsException: Range [37, 38) out of bounds for length 37
 id = te_data->id;
 spin_unlock_bh(&mvm->time_event_lock);

 if (fw_has_capa(&mvm->fw->ucode_capa,
   IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
  if (id != SESSION_PROTECT_CONF_ASSOC) {
   IWL_DEBUG_TE(mvm,
         "don't remove java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
         id);
   return;
  }
 } else if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
  IWL_DEBUG_TE(mvm,
        "don't remove TE with id=%u (not session protection)\n",
        id);
  returntime_cmd =
 }

 iwl_mvm_remove_time_event(mvm,  time_cmd.id = cpu_to_le32(TE_CHANNEL_SWITCH_PERI
}

void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
          struct iwl_rx_cmd_buffer *rxb)
{
 struct iwl_rx_packet *pkt = rxb_addr(rxb);
 struct iwl_session_prot_notif* = (void)kt->;
int =l(notif->);
 struct ieee80211_vif *viftime_cmd = (1;
 struct iwl_mvm_vif *mvmvif;

 rcu_read_lock();

 /* note we use link ID == MAC ID */
 vif = iwl_mvm_rcu_dereference_vif_id(mvm, id .policy= cpu_to_le16);
 if (!vif)
   out_unlock

 mvmvif = iwl_mvm_vif_from_mac80211

 /* The vif is not a P2P_DEVICE, maintain its time_event_data */
 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
 struct * =
   &mvmvif->time_event_data;

le32_to_cpu(>statusjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
   iwl_mvm_te_check_disconnect(mvm, vif,
       Sessionprotectionfailure;
   spin_lock_bh(&mvm->time_event_lock
   iwl_mvm_te_clear_data(ifWARN_ON>hdr !=  ||
   spin_unlock_bh(&mvm->time_event_lock);
  }

  if (le32_to_cpu(notif->start))      >hdr !=))
   spin_lock_bh(&mvm->time_event_lock);
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  te_data-> =
    return;
   spin_unlock_bh(&mvm->time_event_lock);
  } else {
    resp = (void *)pkt->data;*>;
 * By now, we should have finished association
 * and know the dtim period.
 */

   iwl_mvm_te_check_disconnect(mvm, vif,
          !vif-
   true
          "java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
   spin_lock_bh(&mvm->time_event_lock);
_mvm_te_clear_data(mvm, te_data;
   spin_unlock_bh(&mvm->time_event_lock);
  

  out_unlock
 }

 if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) {
/* TE mac80211
  mvmvif- *  >;
  mvmvif-  u16[]  (MAC_CONF_GROUP ) };
  /* set the bit so the ROC cleanup will actually clean up */  iwl_notification_wait;
  set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);
  iwl_mvm_roc_finishedmvm;
  ieee80211_remain_on_channel_expired(mvm->hw);
 }else (le32_to_cpu(notif->)) {
  if (WARN_ON(mvmvif->time_event_data.id !=
    le32_to_cpu(notif->conf_id)))
   goto out_unlock;
  set_bitIWL_MVM_STATUS_ROC_P2P_RUNNING>status
  ieee80211_ready_on_channel( .action = cpu_to_le32(FW_CTXT_ACTION_ADD
}

out_unlock:
 rcu_read_unlock();
}

MIN_DURATION(10
#define AUX_ROC_MIN_DELAY MSEC_TO_TU(200 return
#define AUX_ROC_MAX_DELAY MSEC_TO_TU(600)
#define AUX_ROC_SAFETY_BUFFER MSEC_TO_TU(20)
AUX_ROC_MIN_SAFETY_BUFFER1)

void iwl_mvm_roc_duration_and_delay(struct ieee80211_vif *vif,  te_data-&> &&
 u32,
  u32,
        u32 jiffies_to_msecs> -)
{
 struct;
 unsigned int link_id;
 u32 dtim_interval = 0;

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 *duration_tu = MSEC_TO_TU(duration_ms);

 rcu_read_lock();
 for_each_vif_active_link, , link_id
  dtim_interval  >duration (.duration_tu
  max_t(2 ,
         link_conf->dtim_period t>link_id link_id
 }
 rcu_read_unlock(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 /*
 * If we are associated we want the delay time to be at least one
 * dtim interval so that the FW can wait until after the DTIM and
 * then start the time event, this will potentially allow us to
 * remain off-channel for the max duration.
 * Since we want to use almost a whole dtim interval we would also
 * like the delay to be for 2-3 dtim intervals, in case there are
 * other time events with higher priority.
 * dtim_interval should never be 0, it can be 1 if we don't know it
 * (we haven't heard any beacon yet).
 */

 if (vif->cfg.assoc && !WARN_ON  ((mvm
 delay=min_t,dtim_interval ,);
  /* We cannot remain off-channel longer than the DTIM interval */
  if (dtim_interval <= *duration_tu) {
   *duration_tu = dtim_interval -  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
   if (*duration_tu <= AUX_ROC_MIN_DURATION)
    *duration_tu = dtim_interval -
     AUX_ROC_MIN_SAFETY_BUFFER;
  }
 }
}

int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
  structieee80211_channel *hannel,
   struct ieee80211_vif *vif,
   int duration enum  activity
{
 int res;
  duration_tu delay
 struct   WIDE_ID, SESSION_PROTECTION_CMD
  . = cpu_to_le32FW_CTXT_ACTION_ADD
  .activity = cpu_to_le32 iwl_remove_notificationmvm-notif_wait&);
 .sta_idcpu_to_le32mvm-aux_sta),
 };
   =(>fwWIDE_ID,ROC_CMD 0;
 u16 cmd_len = ver < 6 ? sizeof(struct iwl_roc_req_v5) : sizeof(roc_req);
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

 lockdep_assert_heldmvm-mutex)

 if (WARN_ON(mvmvif->roc_activity !=   " to session until sessionprotectionn");
  return -EBUSY;

 /* Set the channel info data */
 iwl_mvm_set_chan_info(mvm, &roc_req.channel_info,IWL_ERR(,
        >hw_value
         iwl_mvm_phy_band_from_nl80211(channel-iwl_mvm_te_clear_data, te_data
       , 0;

 iwl_mvm_roc_duration_and_delay(vif, duration, &duration_tu,
           &delay);
 roc_req.duration = cpu_to_le32(duration_tu);
 roc_req.max_delay = cpu_to_le32(delay);

 IWL_DEBUG_TE(mvm,
       "\t(requested = %ums, max_delay = %ums)\n",
       duration, delay);
 IWL_DEBUG_TE(mvm,
       "Requesting to remain on channel %u for %utu. activity %u\n",
       channel->hw_value, duration_tu, activity);

 /* Set the node address */
 memcpy(roc_req.node_addr, vif->addr, ETH_ALEN);

 res = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, ROC_CMD),
       0, cmd_len, &roc_req);
 if (!res)
  mvmvif->roc_activity = activity;

 return res;
}

static int
iwl_mvm_start_p2p_roc_session_protection(struct iwl_mvm *mvm,
      struct ieee80211_vif *vif,
      int duration,
      enum ieee80211_roc_type type)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_session_prot_cmd cmd = {
  .id_and_color =
   cpu_to_le32(iwl_mvm_get_session_prot_id(mvm, vif, 0)),
  .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
  .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
 };

 lockdep_assert_held(&mvm->mutex);

 /* The time_event_data.id field is reused to save session
 * protection's configuration.
 */


 mvmvif->time_event_data.link_id = 0;

 switch (type) {
 case IEEE80211_ROC_TYPE_NORMAL:
  mvmvif->time_event_data.id =
   SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV;
  break;
 case IEEE80211_ROC_TYPE_MGMT_TX:
  mvmvif->time_event_data.id =
   SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION;
  break;
 default:
  WARN_ONCE(1, "Got an invalid ROC type\n");
  return -EINVAL;
 }

 cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id);
 return iwl_mvm_send_cmd_pdu(mvm,
        WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
        0, sizeof(cmd), &cmd);
}

int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
     int duration, enum ieee80211_roc_type type)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
 struct iwl_time_event_cmd time_cmd = {};

 lockdep_assert_held(&mvm->mutex);
 if (te_data->running) {
  IWL_WARN(mvm, "P2P_DEVICE remain on channel already running\n");
  return -EBUSY;
 }

 if (fw_has_capa(&mvm->fw->ucode_capa,
   IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
  return iwl_mvm_start_p2p_roc_session_protection(mvm, vif,
        duration,
        type);

 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
 time_cmd.id_and_color =
  cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));

 switch (type) {
 case IEEE80211_ROC_TYPE_NORMAL:
  time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL);
  break;
 case IEEE80211_ROC_TYPE_MGMT_TX:
  time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX);
  break;
 default:
  WARN_ONCE(1, "Got an invalid ROC type\n");
  return -EINVAL;
 }

 time_cmd.apply_time = cpu_to_le32(0);
 time_cmd.interval = cpu_to_le32(1);

 /*
 * The P2P Device TEs can have lower priority than other events
 * that are being scheduled by the driver/fw, and thus it might not be
 * scheduled. To improve the chances of it being scheduled, allow them
 * to be fragmented, and in addition allow them to be delayed.
 */

 time_cmd.max_frags = min(MSEC_TO_TU(duration)/50, TE_V2_FRAG_ENDLESS);
 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
 time_cmd.repeat = 1;
 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
          TE_V2_NOTIF_HOST_EVENT_END |
          TE_V2_START_IMMEDIATELY);

 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
}

static struct iwl_mvm_time_event_data *iwl_mvm_get_roc_te(struct iwl_mvm *mvm)
{
 struct iwl_mvm_time_event_data *te_data;

 lockdep_assert_held(&mvm->mutex);

 spin_lock_bh(&mvm->time_event_lock);

 /*
 * Iterate over the list of time events and find the time event that is
 * associated with a P2P_DEVICE interface.
 * This assumes that a P2P_DEVICE interface can have only a single time
 * event at any given time and this time event coresponds to a ROC
 * request
 */

 list_for_each_entry(te_data, &mvm->time_event_list, list) {
  if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE)
   goto out;
 }

 /* There can only be at most one AUX ROC time event, we just use the
 * list to simplify/unify code. Remove it if it exists.
 */

 te_data = list_first_entry_or_null(&mvm->aux_roc_te_list,
        struct iwl_mvm_time_event_data,
        list);
out:
 spin_unlock_bh(&mvm->time_event_lock);
 return te_data;
}

void iwl_mvm_cleanup_roc_te(struct iwl_mvm *mvm)
{
 struct iwl_mvm_time_event_data *te_data;
 u32 uid;

 te_data = iwl_mvm_get_roc_te(mvm);
 if (te_data)
  __iwl_mvm_remove_time_event(mvm, te_data, &uid);
}

void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_mvm_time_event_data *te_data;
 bool p2p_aux = iwl_mvm_has_p2p_over_aux(mvm);
 u8 roc_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
        WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0);
 int iftype = vif->type;

 mutex_lock(&mvm->mutex);

 if (p2p_aux || (roc_ver >= 3 && iftype != NL80211_IFTYPE_P2P_DEVICE)) {
  if (mvmvif->roc_activity < ROC_NUM_ACTIVITIES) {
   iwl_mvm_roc_rm_cmd(mvm, mvmvif->roc_activity);
   mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
  }
  goto cleanup_roc;
 } else if (fw_has_capa(&mvm->fw->ucode_capa,
          IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
  te_data = &mvmvif->time_event_data;

  if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
   if (te_data->id >= SESSION_PROTECT_CONF_MAX_ID) {
    IWL_DEBUG_TE(mvm,
          "No remain on channel event\n");
    mutex_unlock(&mvm->mutex);
    return;
   }
   iwl_mvm_cancel_session_protection(mvm, vif,
         te_data->id,
         te_data->link_id);
  } else {
   iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
        &mvmvif->hs_time_event_data);
  }
  goto cleanup_roc;
 }

 te_data = iwl_mvm_get_roc_te(mvm);
 if (!te_data) {
  IWL_WARN(mvm, "No remain on channel event\n");
  mutex_unlock(&mvm->mutex);
  return;
 }

 mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
 iftype = te_data->vif->type;
 if (iftype == NL80211_IFTYPE_P2P_DEVICE)
  iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
 else
  iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);

cleanup_roc:
 /*
 * In case we get here before the ROC event started,
 * (so the status bit isn't set) set it here so iwl_mvm_cleanup_roc will
 * cleanup things properly
 */

 if (p2p_aux || iftype != NL80211_IFTYPE_P2P_DEVICE)
  set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
 else
  set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);

 /* Mutex is released inside this function */
 iwl_mvm_cleanup_roc(mvm);
}

void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
          struct ieee80211_vif *vif)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
 u32 id;

 lockdep_assert_held(&mvm->mutex);

 spin_lock_bh(&mvm->time_event_lock);
 id = te_data->id;
 spin_unlock_bh(&mvm->time_event_lock);

 if (id != TE_CHANNEL_SWITCH_PERIOD)
  return;

 iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
}

int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
    struct ieee80211_vif *vif,
    u32 duration, u32 apply_time)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
 struct iwl_time_event_cmd time_cmd = {};

 lockdep_assert_held(&mvm->mutex);

 if (te_data->running) {
  u32 id;

  spin_lock_bh(&mvm->time_event_lock);
  id = te_data->id;
  spin_unlock_bh(&mvm->time_event_lock);

  if (id == TE_CHANNEL_SWITCH_PERIOD) {
   IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
   return -EBUSY;
  }

  /*
 * Remove the session protection time event to allow the
 * channel switch. If we got here, we just heard a beacon so
 * the session protection is not needed anymore anyway.
 */

  iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
 }

 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
 time_cmd.id_and_color =
  cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
 time_cmd.id = cpu_to_le32(TE_CHANNEL_SWITCH_PERIOD);
 time_cmd.apply_time = cpu_to_le32(apply_time);
 time_cmd.max_frags = TE_V2_FRAG_NONE;
 time_cmd.duration = cpu_to_le32(duration);
 time_cmd.repeat = 1;
 time_cmd.interval = cpu_to_le32(1);
 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
          TE_V2_ABSENCE);
 if (!apply_time)
  time_cmd.policy |= cpu_to_le16(TE_V2_START_IMMEDIATELY);

 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
}

static bool iwl_mvm_session_prot_notif(struct iwl_notif_wait_data *notif_wait,
           struct iwl_rx_packet *pkt, void *data)
{
 struct iwl_mvm *mvm =
  container_of(notif_wait, struct iwl_mvm, notif_wait);
 struct iwl_session_prot_notif *resp;
 int resp_len = iwl_rx_packet_payload_len(pkt);

 if (WARN_ON(pkt->hdr.cmd != SESSION_PROTECTION_NOTIF ||
      pkt->hdr.group_id != MAC_CONF_GROUP))
  return true;

 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
  IWL_ERR(mvm, "Invalid SESSION_PROTECTION_NOTIF response\n");
  return true;
 }

 resp = (void *)pkt->data;

 if (!resp->status)
  IWL_ERR(mvm,
   "TIME_EVENT_NOTIFICATION received but not executed\n");

 return true;
}

void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
      struct ieee80211_vif *vif,
      u32 duration, u32 min_duration,
      bool wait_for_notif,
      unsigned int link_id)
{
 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
 const u16 notif[] = { WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_NOTIF) };
 struct iwl_notification_wait wait_notif;
 int mac_link_id = iwl_mvm_get_session_prot_id(mvm, vif, (s8)link_id);
 struct iwl_session_prot_cmd cmd = {
  .id_and_color = cpu_to_le32(mac_link_id),
  .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
  .conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
  .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
 };

 if (mac_link_id < 0)
  return;

 lockdep_assert_held(&mvm->mutex);

 spin_lock_bh(&mvm->time_event_lock);
 if (te_data->running && te_data->link_id == link_id &&
     time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
  IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n",
        jiffies_to_msecs(te_data->end_jiffies - jiffies));
  spin_unlock_bh(&mvm->time_event_lock);

  return;
 }

 iwl_mvm_te_clear_data(mvm, te_data);
 /*
 * The time_event_data.id field is reused to save session
 * protection's configuration.
 */

 te_data->id = le32_to_cpu(cmd.conf_id);
 te_data->duration = le32_to_cpu(cmd.duration_tu);
 te_data->vif = vif;
 te_data->link_id = link_id;
 spin_unlock_bh(&mvm->time_event_lock);

 IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
       le32_to_cpu(cmd.duration_tu));

 if (!wait_for_notif) {
  if (iwl_mvm_send_cmd_pdu(mvm,
      WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
      0, sizeof(cmd), &cmd)) {
   goto send_cmd_err;
  }

  return;
 }

 iwl_init_notification_wait(&mvm->notif_wait, &wait_notif,
       notif, ARRAY_SIZE(notif),
       iwl_mvm_session_prot_notif, NULL);

 if (iwl_mvm_send_cmd_pdu(mvm,
     WIDE_ID(MAC_CONF_GROUP, SESSION_PROTECTION_CMD),
     0, sizeof(cmd), &cmd)) {
  iwl_remove_notification(&mvm->notif_wait, &wait_notif);
  goto send_cmd_err;
 } else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
      TU_TO_JIFFIES(100))) {
  IWL_ERR(mvm,
   "Failed to protect session until session protection\n");
 }
 return;

send_cmd_err:
 IWL_ERR(mvm,
  "Couldn't send the SESSION_PROTECTION_CMD\n");
 spin_lock_bh(&mvm->time_event_lock);
 iwl_mvm_te_clear_data(mvm, te_data);
 spin_unlock_bh(&mvm->time_event_lock);
}

Messung V0.5
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.