aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192de/fw.c')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/fw.c103
1 files changed, 48 insertions, 55 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
index db6972ffe503..b84f10d60c0d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
@@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw,
124 u32 pagenums, remainSize; 124 u32 pagenums, remainSize;
125 u32 page, offset; 125 u32 page, offset;
126 126
127 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); 127 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
128 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) 128 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
129 _rtl92d_fill_dummy(bufferPtr, &size); 129 _rtl92d_fill_dummy(bufferPtr, &size);
130 pagenums = size / FW_8192D_PAGE_SIZE; 130 pagenums = size / FW_8192D_PAGE_SIZE;
131 remainSize = size % FW_8192D_PAGE_SIZE; 131 remainSize = size % FW_8192D_PAGE_SIZE;
132 if (pagenums > 8) { 132 if (pagenums > 8) {
133 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 133 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
134 ("Page numbers should not greater then 8\n")); 134 "Page numbers should not greater then 8\n");
135 } 135 }
136 for (page = 0; page < pagenums; page++) { 136 for (page = 0; page < pagenums; page++) {
137 offset = page * FW_8192D_PAGE_SIZE; 137 offset = page * FW_8192D_PAGE_SIZE;
@@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
158 (!(value32 & FWDL_ChkSum_rpt))); 158 (!(value32 & FWDL_ChkSum_rpt)));
159 if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { 159 if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
160 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 160 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
161 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", 161 "chksum report faill ! REG_MCUFWDL:0x%08x\n",
162 value32)); 162 value32);
163 return -EIO; 163 return -EIO;
164 } 164 }
165 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 165 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
166 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); 166 "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
167 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 167 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
168 value32 |= MCUFWDL_RDY; 168 value32 |= MCUFWDL_RDY;
169 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); 169 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
@@ -188,7 +188,7 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
188 } 188 }
189 RT_ASSERT((delay > 0), ("8051 reset failed!\n")); 189 RT_ASSERT((delay > 0), ("8051 reset failed!\n"));
190 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 190 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
191 ("=====> 8051 reset success (%d) .\n", delay)); 191 "=====> 8051 reset success (%d)\n", delay);
192} 192}
193 193
194static int _rtl92d_fw_init(struct ieee80211_hw *hw) 194static int _rtl92d_fw_init(struct ieee80211_hw *hw)
@@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
197 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 197 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
198 u32 counter; 198 u32 counter;
199 199
200 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n")); 200 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
201 /* polling for FW ready */ 201 /* polling for FW ready */
202 counter = 0; 202 counter = 0;
203 do { 203 do {
@@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
205 if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & 205 if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
206 MAC0_READY) { 206 MAC0_READY) {
207 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 207 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
208 ("Polling FW ready success!! " 208 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
209 "REG_MCUFWDL: 0x%x .\n",
210 rtl_read_byte(rtlpriv, 209 rtl_read_byte(rtlpriv,
211 FW_MAC0_READY))); 210 FW_MAC0_READY));
212 return 0; 211 return 0;
213 } 212 }
214 udelay(5); 213 udelay(5);
@@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
216 if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & 215 if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
217 MAC1_READY) { 216 MAC1_READY) {
218 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 217 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
219 ("Polling FW ready success!! " 218 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
220 "REG_MCUFWDL: 0x%x .\n",
221 rtl_read_byte(rtlpriv, 219 rtl_read_byte(rtlpriv,
222 FW_MAC1_READY))); 220 FW_MAC1_READY));
223 return 0; 221 return 0;
224 } 222 }
225 udelay(5); 223 udelay(5);
@@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
228 226
229 if (rtlhal->interfaceindex == 0) { 227 if (rtlhal->interfaceindex == 0) {
230 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 228 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
231 ("Polling FW ready fail!! MAC0 FW init not ready: " 229 "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
232 "0x%x .\n", 230 rtl_read_byte(rtlpriv, FW_MAC0_READY));
233 rtl_read_byte(rtlpriv, FW_MAC0_READY)));
234 } else { 231 } else {
235 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 232 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
236 ("Polling FW ready fail!! MAC1 FW init not ready: " 233 "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
237 "0x%x .\n", 234 rtl_read_byte(rtlpriv, FW_MAC1_READY));
238 rtl_read_byte(rtlpriv, FW_MAC1_READY)));
239 } 235 }
240 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 236 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
241 ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n", 237 "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n",
242 rtl_read_dword(rtlpriv, REG_MCUFWDL))); 238 rtl_read_dword(rtlpriv, REG_MCUFWDL));
243 return -1; 239 return -1;
244} 240}
245 241
@@ -264,13 +260,13 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
264 pfwdata = (u8 *) rtlhal->pfirmware; 260 pfwdata = (u8 *) rtlhal->pfirmware;
265 rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); 261 rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
266 rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); 262 rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
267 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d)," 263 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
268 "FirmwareSubVersion(%d), Signature(%#x)\n", 264 "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
269 rtlhal->fw_version, rtlhal->fw_subversion, 265 rtlhal->fw_version, rtlhal->fw_subversion,
270 GET_FIRMWARE_HDR_SIGNATURE(pfwheader))); 266 GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
271 if (IS_FW_HEADER_EXIST(pfwheader)) { 267 if (IS_FW_HEADER_EXIST(pfwheader)) {
272 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 268 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
273 ("Shift 32 bytes for FW header!!\n")); 269 "Shift 32 bytes for FW header!!\n");
274 pfwdata = pfwdata + 32; 270 pfwdata = pfwdata + 32;
275 fwsize = fwsize - 32; 271 fwsize = fwsize - 32;
276 } 272 }
@@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
302 break; 298 break;
303 else 299 else
304 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 300 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
305 ("Wait for another mac " 301 "Wait for another mac download fw\n");
306 "download fw\n"));
307 } 302 }
308 spin_lock_irqsave(&globalmutex_for_fwdownload, flags); 303 spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
309 value = rtl_read_byte(rtlpriv, 0x1f); 304 value = rtl_read_byte(rtlpriv, 0x1f);
@@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
337 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); 332 spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
338 if (err) { 333 if (err) {
339 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 334 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
340 ("fw is not ready to run!\n")); 335 "fw is not ready to run!\n");
341 goto exit; 336 goto exit;
342 } else { 337 } else {
343 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 338 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n");
344 ("fw is ready to run!\n"));
345 } 339 }
346exit: 340exit:
347 err = _rtl92d_fw_init(hw); 341 err = _rtl92d_fw_init(hw);
@@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
381 375
382 if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { 376 if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
383 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 377 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
384 ("Return as RF is off!!!\n")); 378 "Return as RF is off!!!\n");
385 return; 379 return;
386 } 380 }
387 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); 381 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
388 while (true) { 382 while (true) {
389 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 383 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
390 if (rtlhal->h2c_setinprogress) { 384 if (rtlhal->h2c_setinprogress) {
391 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 385 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
392 ("H2C set in progress! Wait to set.." 386 "H2C set in progress! Wait to set..element_id(%d)\n",
393 "element_id(%d).\n", element_id)); 387 element_id);
394 388
395 while (rtlhal->h2c_setinprogress) { 389 while (rtlhal->h2c_setinprogress) {
396 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, 390 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
397 flag); 391 flag);
398 h2c_waitcounter++; 392 h2c_waitcounter++;
399 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 393 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
400 ("Wait 100 us (%d times)...\n", 394 "Wait 100 us (%d times)...\n",
401 h2c_waitcounter)); 395 h2c_waitcounter);
402 udelay(100); 396 udelay(100);
403 397
404 if (h2c_waitcounter > 1000) 398 if (h2c_waitcounter > 1000)
@@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
418 wait_writeh2c_limmit--; 412 wait_writeh2c_limmit--;
419 if (wait_writeh2c_limmit == 0) { 413 if (wait_writeh2c_limmit == 0) {
420 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 414 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
421 ("Write H2C fail because no trigger " 415 "Write H2C fail because no trigger for FW INT!\n");
422 "for FW INT!\n"));
423 break; 416 break;
424 } 417 }
425 boxnum = rtlhal->last_hmeboxnum; 418 boxnum = rtlhal->last_hmeboxnum;
@@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
442 break; 435 break;
443 default: 436 default:
444 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 437 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
445 ("switch case not process\n")); 438 "switch case not processed\n");
446 break; 439 break;
447 } 440 }
448 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); 441 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
@@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
450 wait_h2c_limmit--; 443 wait_h2c_limmit--;
451 if (wait_h2c_limmit == 0) { 444 if (wait_h2c_limmit == 0) {
452 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 445 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
453 ("Wating too long for FW read " 446 "Waiting too long for FW read clear HMEBox(%d)!\n",
454 "clear HMEBox(%d)!\n", boxnum)); 447 boxnum);
455 break; 448 break;
456 } 449 }
457 udelay(10); 450 udelay(10);
458 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); 451 isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
459 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); 452 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
460 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 453 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
461 ("Wating for FW read clear HMEBox(%d)!!! " 454 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
462 "0x1BF = %2x\n", boxnum, u1b_tmp)); 455 boxnum, u1b_tmp);
463 } 456 }
464 if (!isfw_read) { 457 if (!isfw_read) {
465 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 458 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
466 ("Write H2C register BOX[%d] fail!!!!! " 459 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
467 "Fw do not read.\n", boxnum)); 460 boxnum);
468 break; 461 break;
469 } 462 }
470 memset(boxcontent, 0, sizeof(boxcontent)); 463 memset(boxcontent, 0, sizeof(boxcontent));
471 memset(boxextcontent, 0, sizeof(boxextcontent)); 464 memset(boxextcontent, 0, sizeof(boxextcontent));
472 boxcontent[0] = element_id; 465 boxcontent[0] = element_id;
473 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 466 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
474 ("Write element_id box_reg(%4x) = %2x\n", 467 "Write element_id box_reg(%4x) = %2x\n",
475 box_reg, element_id)); 468 box_reg, element_id);
476 switch (cmd_len) { 469 switch (cmd_len) {
477 case 1: 470 case 1:
478 boxcontent[0] &= ~(BIT(7)); 471 boxcontent[0] &= ~(BIT(7));
@@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
519 break; 512 break;
520 default: 513 default:
521 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 514 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
522 ("switch case not process\n")); 515 "switch case not processed\n");
523 break; 516 break;
524 } 517 }
525 bwrite_sucess = true; 518 bwrite_sucess = true;
@@ -527,13 +520,13 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
527 if (rtlhal->last_hmeboxnum == 4) 520 if (rtlhal->last_hmeboxnum == 4)
528 rtlhal->last_hmeboxnum = 0; 521 rtlhal->last_hmeboxnum = 0;
529 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, 522 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
530 ("pHalData->last_hmeboxnum = %d\n", 523 "pHalData->last_hmeboxnum = %d\n",
531 rtlhal->last_hmeboxnum)); 524 rtlhal->last_hmeboxnum);
532 } 525 }
533 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); 526 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
534 rtlhal->h2c_setinprogress = false; 527 rtlhal->h2c_setinprogress = false;
535 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); 528 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
536 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); 529 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
537} 530}
538 531
539void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, 532void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
@@ -559,7 +552,7 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
559 u8 u1_h2c_set_pwrmode[3] = { 0 }; 552 u8 u1_h2c_set_pwrmode[3] = { 0 };
560 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 553 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
561 554
562 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); 555 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
563 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); 556 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
564 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); 557 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
565 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, 558 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
@@ -771,14 +764,14 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
771 dlok = true; 764 dlok = true;
772 if (dlok) { 765 if (dlok) {
773 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 766 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
774 ("Set RSVD page location to Fw.\n")); 767 "Set RSVD page location to Fw\n");
775 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, 768 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
776 "H2C_RSVDPAGE", u1RsvdPageLoc, 3); 769 "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
777 rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, 770 rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
778 sizeof(u1RsvdPageLoc), u1RsvdPageLoc); 771 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
779 } else 772 } else
780 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 773 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
781 ("Set RSVD page location to Fw FAIL!!!!!!.\n")); 774 "Set RSVD page location to Fw FAIL!!!!!!\n");
782} 775}
783 776
784void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) 777void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)