wlan_scan_api.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /*
  2. * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  3. * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /*
  20. * DOC: contains scan api
  21. */
  22. #ifndef _WLAN_SCAN_API_H_
  23. #define _WLAN_SCAN_API_H_
  24. #include <wlan_objmgr_psoc_obj.h>
  25. #include <wlan_objmgr_pdev_obj.h>
  26. #include <wlan_objmgr_vdev_obj.h>
  27. #include "../../core/src/wlan_scan_main.h"
  28. #ifdef FEATURE_SET
  29. /**
  30. * wlan_scan_get_feature_info() - Get scan feature set info
  31. * @psoc: pointer to psoc object
  32. * @scan_feature_set: feature set info which needs to be filled
  33. *
  34. * Return: none
  35. */
  36. void wlan_scan_get_feature_info(struct wlan_objmgr_psoc *psoc,
  37. struct wlan_scan_features *scan_feature_set);
  38. #endif
  39. /**
  40. * wlan_scan_get_scan_entry_by_mac_freq() - API to get scan entry
  41. * info from scan db by mac addr
  42. * @pdev: pointer to pdev object
  43. * @bssid: pointer to mac addr
  44. * @freq: frequency for scan filter
  45. *
  46. * Return: scan entry if found, else NULL
  47. */
  48. struct scan_cache_entry *
  49. wlan_scan_get_scan_entry_by_mac_freq(struct wlan_objmgr_pdev *pdev,
  50. struct qdf_mac_addr *bssid,
  51. uint16_t freq);
  52. /**
  53. * wlan_scan_cfg_set_active_2g_dwelltime() - API to set scan active 2g dwelltime
  54. * @psoc: pointer to psoc object
  55. * @dwell_time: scan active dwell time
  56. *
  57. * Return: none
  58. */
  59. void wlan_scan_cfg_set_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
  60. uint32_t dwell_time);
  61. /**
  62. * wlan_scan_cfg_get_active_2g_dwelltime() - API to get active 2g dwelltime
  63. * @psoc: pointer to psoc object
  64. * @dwell_time: scan active dwelltime
  65. *
  66. * Return: scan active dwell time
  67. */
  68. void wlan_scan_cfg_get_active_2g_dwelltime(struct wlan_objmgr_psoc *psoc,
  69. uint32_t *dwell_time);
  70. #ifdef CONFIG_BAND_6GHZ
  71. /**
  72. * wlan_scan_cfg_set_active_6g_dwelltime() - API to set scan active 6g dwelltime
  73. * @psoc: pointer to psoc object
  74. * @dwell_time: scan active dwell time
  75. *
  76. * Return: QDF_STATUS
  77. */
  78. QDF_STATUS wlan_scan_cfg_set_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
  79. uint32_t dwell_time);
  80. /**
  81. * wlan_scan_cfg_get_active_6g_dwelltime() - API to get active 6g dwelltime
  82. * @psoc: pointer to psoc object
  83. * @dwell_time: scan active dwelltime
  84. *
  85. * Return: QDF_STATUS
  86. */
  87. QDF_STATUS wlan_scan_cfg_get_active_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
  88. uint32_t *dwell_time);
  89. /**
  90. * wlan_scan_cfg_set_passive_6g_dwelltime() - API to set scan passive 6g
  91. * dwelltime
  92. * @psoc: pointer to psoc object
  93. * @dwell_time: scan passive dwell time
  94. *
  95. * Return: QDF_STATUS
  96. */
  97. QDF_STATUS wlan_scan_cfg_set_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
  98. uint32_t dwell_time);
  99. /**
  100. * wlan_scan_cfg_get_passive_6g_dwelltime() - API to get passive 6g dwelltime
  101. * @psoc: pointer to psoc object
  102. * @dwell_time: scan passive dwelltime
  103. *
  104. * Return: QDF_STATUS
  105. */
  106. QDF_STATUS wlan_scan_cfg_get_passive_6g_dwelltime(struct wlan_objmgr_psoc *psoc,
  107. uint32_t *dwell_time);
  108. /**
  109. * wlan_scan_cfg_get_min_dwelltime_6g() - API to get minimum 6g dwelltime
  110. * @psoc: pointer to psoc object
  111. * @min_dwell_time_6ghz: minimum dwelltime 6g
  112. *
  113. * Return: QDF_STATUS
  114. */
  115. void wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc *psoc,
  116. uint32_t *min_dwell_time_6ghz);
  117. /**
  118. * wlan_scan_cfg_set_scan_mode_6g() - API to set scan mode for 6 GHz
  119. * @psoc: pointer to psoc object
  120. * @scan_mode_6g: scan mode value for 6 GHz
  121. *
  122. * Return: QDF_STATUS
  123. */
  124. QDF_STATUS wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc *psoc,
  125. enum scan_mode_6ghz scan_mode_6g);
  126. #else
  127. static inline
  128. void wlan_scan_cfg_get_min_dwelltime_6g(struct wlan_objmgr_psoc *psoc,
  129. uint32_t *min_dwell_time_6ghz)
  130. {
  131. }
  132. static inline
  133. QDF_STATUS wlan_scan_cfg_set_scan_mode_6g(struct wlan_objmgr_psoc *psoc,
  134. enum scan_mode_6ghz scan_mode_6g)
  135. {
  136. return QDF_STATUS_E_NOSUPPORT;
  137. }
  138. #endif
  139. /**
  140. * wlan_scan_cfg_set_active_dwelltime() - API to set scan active dwelltime
  141. * @psoc: pointer to psoc object
  142. * @dwell_time: scan active dwell time
  143. *
  144. * Return: none
  145. */
  146. void wlan_scan_cfg_set_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  147. uint32_t dwell_time);
  148. /**
  149. * wlan_scan_cfg_get_active_dwelltime() - API to get active dwelltime
  150. * @psoc: pointer to psoc object
  151. * @dwell_time: scan active dwelltime
  152. *
  153. * Return: scan active dwell time
  154. */
  155. void wlan_scan_cfg_get_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  156. uint32_t *dwell_time);
  157. /**
  158. * wlan_scan_cfg_set_passive_dwelltime() - API to set scan passive dwelltime
  159. * @psoc: pointer to psoc object
  160. * @dwell_time: scan passive dwell time
  161. *
  162. * Return: none
  163. */
  164. void wlan_scan_cfg_set_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  165. uint32_t dwell_time);
  166. /**
  167. * wlan_scan_cfg_get_passive_dwelltime() - API to get passive dwelltime
  168. * @psoc: pointer to psoc object
  169. * @dwell_time: scan passive dwelltime
  170. *
  171. * Return: scan passive dwell time
  172. */
  173. void wlan_scan_cfg_get_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  174. uint32_t *dwell_time);
  175. #ifdef WLAN_POLICY_MGR_ENABLE
  176. /*
  177. * wlan_scan_update_pno_dwell_time() - update active and passive dwell time
  178. * depending on active concurrency modes
  179. * @vdev: vdev object pointer
  180. * @req: scan request
  181. *
  182. * Return: void
  183. */
  184. void wlan_scan_update_pno_dwell_time(struct wlan_objmgr_vdev *vdev,
  185. struct pno_scan_req_params *req,
  186. struct scan_default_params *scan_def);
  187. /*
  188. * wlan_scan_update_low_latency_profile_chnlist() - Low latency SAP + scan
  189. * concurrencies
  190. * @vdev: vdev object pointer
  191. * @req: scan request
  192. *
  193. * Return: void
  194. */
  195. void wlan_scan_update_low_latency_profile_chnlist(
  196. struct wlan_objmgr_vdev *vdev,
  197. struct scan_start_request *req);
  198. #else
  199. static inline
  200. void wlan_scan_update_low_latency_profile_chnlist(
  201. struct wlan_objmgr_vdev *vdev,
  202. struct scan_start_request *req)
  203. {
  204. }
  205. #endif
  206. /**
  207. * wlan_scan_cfg_get_conc_active_dwelltime() - Get concurrent active dwelltime
  208. * @psoc: pointer to psoc object
  209. * @dwell_time: scan active dwelltime
  210. *
  211. * Return: scan concurrent active dwell time
  212. */
  213. void wlan_scan_cfg_get_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  214. uint32_t *dwell_time);
  215. /**
  216. * wlan_scan_cfg_set_conc_active_dwelltime() - Set concurrent active dwelltime
  217. * @psoc: pointer to psoc object
  218. * @dwell_time: scan active dwelltime
  219. *
  220. * Return: scan concurrent active dwell time
  221. */
  222. void wlan_scan_cfg_set_conc_active_dwelltime(struct wlan_objmgr_psoc *psoc,
  223. uint32_t dwell_time);
  224. /**
  225. * wlan_scan_cfg_get_conc_passive_dwelltime() - Get passive concurrent dwelltime
  226. * @psoc: pointer to psoc object
  227. * @dwell_time: scan passive dwelltime
  228. *
  229. * Return: scan concurrent passive dwell time
  230. */
  231. void wlan_scan_cfg_get_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  232. uint32_t *dwell_time);
  233. /**
  234. * wlan_scan_cfg_set_conc_passive_dwelltime() - Set passive concurrent dwelltime
  235. * @psoc: pointer to psoc object
  236. * @dwell_time: scan passive dwelltime
  237. *
  238. * Return: scan concurrent passive dwell time
  239. */
  240. void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
  241. uint32_t dwell_time);
  242. /**
  243. * wlan_scan_cfg_honour_nl_scan_policy_flags() - API to get nl scan policy
  244. * flags honoured
  245. * @psoc: pointer to psoc object
  246. *
  247. * Return: nl scan policy flags honoured or not
  248. */
  249. bool wlan_scan_cfg_honour_nl_scan_policy_flags(struct wlan_objmgr_psoc *psoc);
  250. /**
  251. * wlan_scan_cfg_get_conc_max_resttime() - API to get max rest time
  252. * @psoc: pointer to psoc object
  253. * @rest_time: scan concurrent max resttime
  254. *
  255. * Return: scan concurrent max rest time
  256. */
  257. void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
  258. uint32_t *rest_time);
  259. /**
  260. * wlan_scan_cfg_get_dfs_chan_scan_allowed() - API to get dfs scan enabled
  261. * @psoc: pointer to psoc object
  262. * @enable_dfs_scan: DFS scan enabled or not.
  263. *
  264. * Return: None
  265. */
  266. void wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
  267. bool *enable_dfs_scan);
  268. /**
  269. * wlan_scan_cfg_set_dfs_chan_scan_allowed() - API to set dfs scan enabled.
  270. * @psoc: pointer to psoc object
  271. * @enable_dfs_scan: Set dfs scan enabled or not.
  272. *
  273. * Return: None
  274. */
  275. void wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
  276. bool enable_dfs_scan);
  277. /**
  278. * wlan_scan_cfg_get_conc_min_resttime() - API to get concurrent min rest time
  279. * @psoc: pointer to psoc object
  280. * @rest_time: scan concurrent min rest time
  281. *
  282. * Return: scan concurrent min rest time
  283. */
  284. void wlan_scan_cfg_get_conc_min_resttime(struct wlan_objmgr_psoc *psoc,
  285. uint32_t *rest_time);
  286. /**
  287. * wlan_scan_is_snr_monitor_enabled() - API to get SNR monitoring enabled or not
  288. * @psoc: pointer to psoc object
  289. *
  290. * Return: enable/disable snr monitor mode.
  291. */
  292. bool wlan_scan_is_snr_monitor_enabled(struct wlan_objmgr_psoc *psoc);
  293. /**
  294. * wlan_scan_process_bcn_probe_rx_sync() - handle bcn without posting to
  295. * scheduler thread
  296. * @psoc: psoc context
  297. * @buf: frame buf
  298. * @rx_param: rx event params
  299. * @frm_type: frame type
  300. *
  301. * handle bcn without posting to scheduler thread, this should be called
  302. * while caller is already in scheduler thread context
  303. *
  304. * Return: success or error code.
  305. */
  306. QDF_STATUS
  307. wlan_scan_process_bcn_probe_rx_sync(struct wlan_objmgr_psoc *psoc,
  308. qdf_nbuf_t buf,
  309. struct mgmt_rx_event_params *rx_param,
  310. enum mgmt_frame_type frm_type);
  311. /**
  312. * wlan_scan_get_aging_time - Get the scan aging time config
  313. * @psoc: psoc context
  314. *
  315. * Return: Scan aging time config
  316. */
  317. qdf_time_t wlan_scan_get_aging_time(struct wlan_objmgr_psoc *psoc);
  318. /**
  319. * wlan_scan_set_aging_time - Set the scan aging time config
  320. * @psoc: psoc context
  321. * @time: scan aging time
  322. *
  323. * Return: success or error code.
  324. */
  325. QDF_STATUS wlan_scan_set_aging_time(struct wlan_objmgr_psoc *psoc,
  326. qdf_time_t time);
  327. /**
  328. * wlan_scan_purge_results() - purge the scan list
  329. * @scan_list: scan list to be purged
  330. *
  331. * This function purge the temp scan list
  332. *
  333. * Return: QDF_STATUS
  334. */
  335. static inline QDF_STATUS wlan_scan_purge_results(qdf_list_t *scan_list)
  336. {
  337. return scm_purge_scan_results(scan_list);
  338. }
  339. /**
  340. * wlan_scan_get_result() - The Public API to get scan results
  341. * @pdev: pdev info
  342. * @filter: Filters
  343. *
  344. * This function fetches scan result
  345. *
  346. * Return: scan list pointer
  347. */
  348. static inline qdf_list_t *wlan_scan_get_result(struct wlan_objmgr_pdev *pdev,
  349. struct scan_filter *filter)
  350. {
  351. return scm_get_scan_result(pdev, filter);
  352. }
  353. /**
  354. * wlan_scan_update_mlme_by_bssinfo() - The Public API to update mlme
  355. * info in the scan entry
  356. * @pdev: pdev object
  357. * @bss_info: bssid info to find the matching scan entry
  358. * @mlme_info: mlme info to be updated.
  359. *
  360. * Return: QDF_STATUS
  361. */
  362. static inline QDF_STATUS
  363. wlan_scan_update_mlme_by_bssinfo(struct wlan_objmgr_pdev *pdev,
  364. struct bss_info *bss_info,
  365. struct mlme_info *mlme_info)
  366. {
  367. return scm_scan_update_mlme_by_bssinfo(pdev, bss_info, mlme_info);
  368. }
  369. /**
  370. * wlan_scan_start() - Public API to start a scan
  371. * @req: start scan req params
  372. *
  373. * The Public API to start a scan. Post a msg to target_if queue
  374. *
  375. * Return: QDF_STATUS.
  376. */
  377. QDF_STATUS wlan_scan_start(struct scan_start_request *req);
  378. /**
  379. * wlan_scan_cancel() - Public API to stop a scan
  380. * @req: stop scan request params
  381. *
  382. * The Public API to stop a scan. Post a msg to target_if queue
  383. *
  384. * Return: QDF_STATUS.
  385. */
  386. QDF_STATUS wlan_scan_cancel(struct scan_cancel_request *req);
  387. /**
  388. * wlan_scan_get_scan_id() - Public API to allocate scan ID
  389. * @psoc: psoc object
  390. *
  391. * Public API, allocates a new scan id for caller
  392. *
  393. * Return: newly allocated scan ID
  394. */
  395. wlan_scan_id
  396. wlan_scan_get_scan_id(struct wlan_objmgr_psoc *psoc);
  397. /**
  398. * wlan_scan_init_default_params() - Public API to initialize scan params
  399. * @vdev: vdev object
  400. * @req: scan request object
  401. *
  402. * Public API to initialize scan start request with defaults scan params
  403. *
  404. * Return: QDF_STATUS_SUCCESS or error code
  405. */
  406. QDF_STATUS
  407. wlan_scan_init_default_params(struct wlan_objmgr_vdev *vdev,
  408. struct scan_start_request *req);
  409. /**
  410. * wlan_scan_register_requester() - Public API, assigns requester ID
  411. * to caller and registers scan event call back handler
  412. * @psoc: psoc object
  413. * @module_name:name of requester module
  414. * @event_cb: event callback function pointer
  415. * @arg: argument to @event_cb
  416. *
  417. * API, allows other components to allocate requester id.
  418. * Normally used by modules at init time to register their callback
  419. * and get one requester id. @event_cb will be invoked for
  420. * all scan events whose requester id matches with @requester.
  421. *
  422. * Return: assigned non zero requester id for success
  423. * zero (0) for failure
  424. */
  425. wlan_scan_requester
  426. wlan_scan_register_requester(struct wlan_objmgr_psoc *psoc,
  427. uint8_t *module_name,
  428. scan_event_handler event_cb,
  429. void *arg);
  430. /**
  431. * wlan_scan_unregister_requester() -Public API, reclaims previously
  432. * allocated requester ID
  433. * @psoc: psoc object
  434. * @requester: requester ID to reclaim.
  435. *
  436. * API, reclaims previously allocated requester id.
  437. *
  438. * Return: void
  439. */
  440. void
  441. wlan_scan_unregister_requester(struct wlan_objmgr_psoc *psoc,
  442. wlan_scan_requester requester);
  443. /**
  444. * wlan_scan_cfg_skip_6g_and_indoor_freq() - API to get 6g and indoor freq
  445. * scan ini val
  446. * @psoc: psoc object
  447. *
  448. * Return: skip 6g and indoor freq scan or not
  449. */
  450. bool wlan_scan_cfg_skip_6g_and_indoor_freq(
  451. struct wlan_objmgr_psoc *psoc);
  452. /**
  453. * wlan_scan_register_mbssid_cb() - register api to inform bcn/probe rsp
  454. * @psoc: psoc object
  455. * @cb: callback to be registered
  456. *
  457. * Return: QDF_STATUS
  458. */
  459. QDF_STATUS wlan_scan_register_mbssid_cb(struct wlan_objmgr_psoc *psoc,
  460. update_mbssid_bcn_prb_rsp cb);
  461. /**
  462. * wlan_scan_get_entry_by_mac_addr() - Get bcn/probe rsp from scan db
  463. * @pdev: pdev info
  464. * @bssid: BSSID of the bcn/probe response to be fetched from scan db
  465. * @frame: Frame from scan db with given bssid.
  466. *
  467. * This is a wrapper to fetch the bcn/probe rsp frame with given mac address
  468. * through scm_scan_get_entry_by_mac_addr(). scm_scan_get_entry_by_mac_add()
  469. * allocates memory for the frame and it's caller responsibility to free
  470. * the memory once it's done with the usage i.e. frame->ptr.
  471. *
  472. * Return: QDF_STATUS_SUCCESS if scan entry is present in db
  473. */
  474. QDF_STATUS
  475. wlan_scan_get_entry_by_mac_addr(struct wlan_objmgr_pdev *pdev,
  476. struct qdf_mac_addr *bssid,
  477. struct element_info *frame);
  478. /**
  479. * wlan_scan_get_last_scan_ageout_time() - API to get last scan
  480. * ageout time
  481. * @psoc: psoc object
  482. * @last_scan_ageout_time: last scan ageout time
  483. *
  484. * Return: void
  485. */
  486. void
  487. wlan_scan_get_last_scan_ageout_time(struct wlan_objmgr_psoc *psoc,
  488. uint32_t *last_scan_ageout_time);
  489. /**
  490. * wlan_scan_get_entry_by_bssid() - function to get scan entry by bssid
  491. * @pdev: pdev object
  492. * @bssid: bssid to be fetched from scan db
  493. *
  494. * Return : scan entry if found, else NULL
  495. */
  496. struct scan_cache_entry *
  497. wlan_scan_get_entry_by_bssid(struct wlan_objmgr_pdev *pdev,
  498. struct qdf_mac_addr *bssid);
  499. /**
  500. * wlan_scan_get_mld_addr_by_link_addr() - Function to get MLD address
  501. * in the scan entry from the link BSSID.
  502. * @pdev: pdev object
  503. * @link_addr: Link BSSID to match the scan filter
  504. * @mld_mac_addr: Pointer to fill the MLD address.
  505. *
  506. * A wrapper API which fills @mld_mac_addr with MLD address of scan entry
  507. * whose bssid field matches @link_addr.
  508. *
  509. * Return: QDF_STATUS
  510. */
  511. QDF_STATUS
  512. wlan_scan_get_mld_addr_by_link_addr(struct wlan_objmgr_pdev *pdev,
  513. struct qdf_mac_addr *link_addr,
  514. struct qdf_mac_addr *mld_mac_addr);
  515. /**
  516. * wlan_scan_get_aux_support() - get aux scan policy
  517. * @psoc: psoc object
  518. *
  519. * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type.
  520. *
  521. * Return: true/false
  522. */
  523. bool wlan_scan_get_aux_support(struct wlan_objmgr_psoc *psoc);
  524. static inline bool
  525. wlan_scan_entries_contain_cmn_akm(struct scan_cache_entry *entry1,
  526. struct scan_cache_entry *entry2)
  527. {
  528. return scm_scan_entries_contain_cmn_akm(entry1, entry2);
  529. }
  530. #endif