⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtusb_io.c

📁 RT73在嵌入式领域最稳定的驱动 官网已经取消下载
💻 C
📖 第 1 页 / 共 4 页
字号:
						Value |= ((LENGTH_802_11 << 3) | (pAd->PortCfg.CipherAlg));
						RTUSBWriteMACRegister_old(pAd, TXRX_CSR0, Value);
#endif
					}
					else if (WepStatus == Ndis802_11Encryption3Enabled)
					{
						DBGPRINT(RT_DEBUG_ERROR, " AES  !!!  \n");
						pAd->SharedKey[pAd->PortCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
#if 0
						RTUSBReadMACRegister_old(pAd, TXRX_CSR0, &Value);
						Value &= 0xfe00;
						Value |= ((LENGTH_802_11 << 3) | (pAd->PortCfg.CipherAlg));
						RTUSBWriteMACRegister_old(pAd, TXRX_CSR0, Value);
#endif
					}
					else if (WepStatus == Ndis802_11EncryptionDisabled)
					{
						DBGPRINT(RT_DEBUG_ERROR, " CIPHER_NONE  !!!  \n");

						pAd->SharedKey[pAd->PortCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
#if 0
						RTUSBReadMACRegister_old(pAd, TXRX_CSR0, &Value);
						Value &= 0xfe00;
						RTUSBWriteMACRegister_old(pAd, TXRX_CSR0, Value);
#endif
					}else 
					{
						DBGPRINT(RT_DEBUG_ERROR, " ERROR Cipher   !!!  \n");
					}
#endif
				}
			break;
#endif
			case OID_802_11_ADD_WEP:
			{
				ULONG	KeyIdx;
				PNDIS_802_11_WEP	pWepKey;

				DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_ADD_WEP  \n");
				
				pWepKey = (PNDIS_802_11_WEP)pData;
				KeyIdx = pWepKey->KeyIndex & 0x0fffffff;

				// it is a shared key
				if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
				{
					NdisStatus = NDIS_STATUS_FAILURE;
					DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_ADD_WEP, INVALID_DATA!!\n");
				}
				else 
				{
					UCHAR CipherAlg;
					pAd->SharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
					NdisMoveMemory(pAd->SharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
					CipherAlg = (pAd->SharedKey[KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
					pAd->SharedKey[KeyIdx].CipherAlg = CipherAlg;
					if (pWepKey->KeyIndex & 0x80000000)
					{
						// Default key for tx (shared key)
						pAd->PortCfg.DefaultKeyId = (UCHAR) KeyIdx;
					}							
					AsicAddSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
					DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength);
				}
			}
			break;
			    
			case OID_802_11_REMOVE_WEP:
			{
				ULONG		KeyIdx;

				
				KeyIdx = *(NDIS_802_11_KEY_INDEX *) pData;
				if (KeyIdx & 0x80000000)
				{
					NdisStatus = NDIS_STATUS_FAILURE;
					DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_WEP, INVALID_DATA!!\n");
				}
				else
				{
					KeyIdx = KeyIdx & 0x0fffffff;
					if (KeyIdx >= 4)
					{
						NdisStatus = NDIS_STATUS_FAILURE;
						DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_WEP, Invalid KeyIdx[=%d]!!\n", KeyIdx);
					}
					else
					{
						pAd->SharedKey[KeyIdx].KeyLen = 0;
						pAd->SharedKey[KeyIdx].CipherAlg = CIPHER_NONE;
						AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
						DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_REMOVE_WEP (KeyIdx=%d)\n", KeyIdx);
					}
				}	
			}
			break;

			case OID_802_11_ADD_KEY_WEP:
			{
				PNDIS_802_11_KEY		pKey;
				ULONG					i, KeyIdx;						

				pKey = (PNDIS_802_11_KEY) pData;
				KeyIdx = pKey->KeyIndex & 0x0fffffff;

				// it is a shared key
			    if (KeyIdx >= 4)
				{
			        NdisStatus = NDIS_STATUS_FAILURE;
			        DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_ADD_KEY_WEP, Invalid KeyIdx[=%d]!!\n", KeyIdx);
			    }
			    else 
			    {
			        UCHAR CipherAlg;
					 
			        pAd->SharedKey[KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
			        NdisMoveMemory(pAd->SharedKey[KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);

			        if (pKey->KeyLength == 5)
				        CipherAlg = CIPHER_WEP64;
				    else
				        CipherAlg = CIPHER_WEP128;

				    // always expand the KEY to 16-byte here for efficiency sake. so that in case CKIP is used
				    // sometime later we don't have to do key expansion for each TX in RTUSBHardTransmit().
				    // However, we shouldn't change pAd->SharedKey[BSS0][KeyIdx].KeyLen
				    if (pKey->KeyLength < 16)
				    {
				        for(i = 1; i < (16 / pKey->KeyLength); i++)
				        {
				            NdisMoveMemory(&pAd->SharedKey[KeyIdx].Key[i * pKey->KeyLength], 
										   &pKey->KeyMaterial[0], 
										   pKey->KeyLength);
				        }
					    NdisMoveMemory(&pAd->SharedKey[KeyIdx].Key[i * pKey->KeyLength], 
									   &pKey->KeyMaterial[0], 
									   16 - (i * pKey->KeyLength));
				    }

				    pAd->SharedKey[KeyIdx].CipherAlg = CipherAlg;
				    if (pKey->KeyIndex & 0x80000000)
					{
				        // Default key for tx (shared key)
					    pAd->PortCfg.DefaultKeyId = (UCHAR) KeyIdx;
				    }

				    AsicAddSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx, CipherAlg, pAd->SharedKey[KeyIdx].Key, NULL, NULL);
				    DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_ADD_KEY_WEP (KeyIdx=%d, KeyLen=%d, CipherAlg=%d)\n", 
				        pAd->PortCfg.DefaultKeyId, pAd->SharedKey[KeyIdx].KeyLen, pAd->SharedKey[KeyIdx].CipherAlg);
				}
			}
			break;

			case OID_802_11_ADD_KEY:
			{  
                PNDIS_802_11_KEY	pkey = (PNDIS_802_11_KEY)pData;
                
				NdisStatus = RTMPWPAAddKeyProc(pAd, pkey);
				RTUSBBulkReceive(pAd);
				DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_ADD_KEY\n");
			}
			break;

#if 0
			case RT_OID_802_11_REMOVE_WEP:
			case OID_802_11_REMOVE_WEP:
			{
				ULONG  KeyIdx;

				
				KeyIdx = *(NDIS_802_11_KEY_INDEX *) pData;
				if (KeyIdx & 0x80000000)
				{
					NdisStatus = NDIS_STATUS_FAILURE;
					DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_WEP, INVALID_DATA!!\n");
				}
				else
				{
					KeyIdx = KeyIdx & 0x0fffffff;
					if (KeyIdx >= 4)
					{
						NdisStatus = NDIS_STATUS_FAILURE;
						DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_WEP, INVALID_DATA!!\n");
					}
						else
					{

					}
				}
			}
			break;
#if 0				
			{
				//PNDIS_802_11_REMOVE_KEY  pRemoveKey;
				ULONG  KeyIdx;
				//pRemoveKey = (PNDIS_802_11_REMOVE_KEY) pData;
				//KeyIdx = pRemoveKey->KeyIndex;


				DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_WEP\n");
				//if (InformationBufferLength != sizeof(NDIS_802_11_KEY_INDEX))
				//	Status = NDIS_STATUS_INVALID_LENGTH;
				//else 
				{
					KeyIdx = *(NDIS_802_11_KEY_INDEX *) pData;

					if (KeyIdx & 0x80000000)
					{
						// Should never set default bit when remove key
						//Status = NDIS_STATUS_INVALID_DATA;
					}
					else
					{
						KeyIdx = KeyIdx & 0x0fffffff;
						if (KeyIdx >= 4)
						{
							//Status = NDIS_STATUS_INVALID_DATA;
						}
						else
						{
							pAd->SharedKey[KeyIdx].KeyLen = 0;
							//Status = RT2573USBEnqueueCmdFromNdis(pAd, OID_802_11_REMOVE_WEP, TRUE, pInformationBuffer, InformationBufferLength);

							AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
						}
					}
				}
			}
			break;
#endif
#endif
			case OID_802_11_REMOVE_KEY:
			{
				PNDIS_802_11_REMOVE_KEY  pRemoveKey;
				ULONG  KeyIdx;
				
				pRemoveKey = (PNDIS_802_11_REMOVE_KEY) pData;
				if (pAd->PortCfg.AuthMode >= Ndis802_11AuthModeWPA)
				{
					NdisStatus = RTMPWPARemoveKeyProc(pAd, pData);
					DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::RTMPWPARemoveKeyProc\n");
				}
				else 
				{
					KeyIdx = pRemoveKey->KeyIndex;
						
					if (KeyIdx & 0x80000000)
					{
						// Should never set default bit when remove key
						NdisStatus = NDIS_STATUS_FAILURE;
						DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_KEY, Invalid KeyIdx[=%d]!!\n", KeyIdx);
					}
					else
					{
						KeyIdx = KeyIdx & 0x0fffffff;
						if (KeyIdx >= 4)
						{
							NdisStatus = NDIS_STATUS_FAILURE;
							DBGPRINT(RT_DEBUG_ERROR, "CMDHandler::OID_802_11_REMOVE_KEY, Invalid KeyIdx[=%d]!!\n", KeyIdx);										
						}
						else
						{
							pAd->SharedKey[KeyIdx].KeyLen = 0;
							pAd->SharedKey[KeyIdx].CipherAlg = CIPHER_NONE;
							AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
							DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::AsicRemoveSharedKeyEntry(KeyIdx=%d)\n", KeyIdx);
						}
					}
				}

			}
			break;
				
			case OID_802_11_POWER_MODE:
			{
				NDIS_802_11_POWER_MODE PowerMode = *(PNDIS_802_11_POWER_MODE) pData;
				DBGPRINT(RT_DEBUG_TRACE, "CMDHandler::OID_802_11_POWER_MODE (=%d)\n",PowerMode);
				
				// save user's policy here, but not change PortCfg.Psm immediately
				if (PowerMode == Ndis802_11PowerModeCAM) 
				{
					// clear PSM bit immediately
					MlmeSetPsmBit(pAd, PWR_ACTIVE);
		        
					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); 
					if (pAd->PortCfg.bWindowsACCAMEnable == FALSE)
						pAd->PortCfg.WindowsPowerMode = PowerMode;
					pAd->PortCfg.WindowsBatteryPowerMode = PowerMode;
				} 
				else if (PowerMode == Ndis802_11PowerModeMAX_PSP) 
				{
					// do NOT turn on PSM bit here, wait until MlmeCheckPsmChange()
					// to exclude certain situations.
					//     MlmeSetPsmBit(pAd, PWR_SAVE);
					if (pAd->PortCfg.bWindowsACCAMEnable == FALSE)
						pAd->PortCfg.WindowsPowerMode = PowerMode;
					pAd->PortCfg.WindowsBatteryPowerMode = PowerMode;
					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); 
					pAd->PortCfg.DefaultListenCount = 5;
				} 
				else if (PowerMode == Ndis802_11PowerModeFast_PSP) 
				{
					// do NOT turn on PSM bit here, wait until MlmeCheckPsmChange()
					// to exclude certain situations.
					//     MlmeSetPsmBit(pAd, PWR_SAVE);
					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
					if (pAd->PortCfg.bWindowsACCAMEnable == FALSE)
						pAd->PortCfg.WindowsPowerMode = PowerMode;
					pAd->PortCfg.WindowsBatteryPowerMode = PowerMode;
					pAd->PortCfg.DefaultListenCount = 3;
				} 
			}					
			break;

			case RT_PERFORM_SOFT_DIVERSITY:
				AsicRxAntEvalAction(pAd);
			break;

		    case RT_OID_FORCE_WAKE_UP:
			    AsicForceWakeup(pAd);
			break;

		    case RT_OID_SET_PSM_BIT_ACTIVE:
			    MlmeSetPsmBit(pAd, PWR_ACTIVE);
		    break;

			default:
			break;
		}

    
		if (cmdqelmt->CmdFromNdis == TRUE)
		{
			if ((cmdqelmt->command != OID_802_11_BSSID_LIST_SCAN) &&
				(cmdqelmt->command != RT_OID_802_11_BSSID) &&
				(cmdqelmt->command != OID_802_11_SSID) &&
				(cmdqelmt->command != OID_802_11_DISASSOCIATE))
			{
			}

			if ((cmdqelmt->command != RT_OID_MULTI_READ_MAC) &&
				(cmdqelmt->command != RT_OID_VENDOR_READ_BBP) &&
#ifdef DBG					
				(cmdqelmt->command != RT_OID_802_11_QUERY_HARDWARE_REGISTER) &&
#endif					
				(cmdqelmt->command != RT_OID_USB_VENDOR_EEPROM_READ))
			{
				if (cmdqelmt->buffer != NULL)
			        kfree(cmdqelmt->buffer);
			}
			
			kfree((PCmdQElmt)cmdqelmt);
		}
		else
            cmdqelmt->InUse = FALSE;
            
	}


}

#ifdef DBG
#define HARDWARE_MAC	0
#define HARDWARE_BBP	1
#define HARDWARE_RF		2
NDIS_STATUS     RTUSBQueryHardWareRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	PVOID			pBuf)
{
	PRT_802_11_HARDWARE_REGISTER	pHardwareRegister;
	ULONG							Value;
	USHORT							Offset;
	UCHAR							bbpValue;
	UCHAR							bbpID;
	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;	

	pHardwareRegister = (PRT_802_11_HARDWARE_REGISTER) pBuf;

	if (pHardwareRegister->HardwareType == HARDWARE_MAC)
	{
		//Check Offset is valid?
		if (pHardwareRegister->Offset > 0xF4)
			Status = NDIS_STATUS_FAILURE;
		
		Offset = (USHORT) pHardwareRegister->Offset;
		RTUSBReadMACRegister(pAd, Offset, &Value);
		pHardwareRegister->Data = Value;
		DBGPRINT(RT_DEBUG_TRACE, "MAC:Offset[0x%04x]=[0x%04x]\n", Offset, Value);
	}
	else if (pHardwareRegister->HardwareType == HARDWARE_BBP)
	{
		bbpID = (UCHAR) pHardwareRegister->Offset;
		
		RTUSBReadBBPRegister(pAd, bbpID, &bbpValue);		
		pHardwareRegister->Data = bbpValue;
		DBGPRINT(RT_DEBUG_TRACE, "BBP:ID[0x%02x]=[0x%02x]\n", bbpID, bbpValue);		
	}
	else
		Status = NDIS_STATUS_FAILURE;
	
	return Status;
}

NDIS_STATUS     RTUSBSetHardWareRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	PVOID			pBuf)
{
	PRT_802_11_HARDWARE_REGISTER	pHardwareRegister;
	ULONG							Value;
	USHORT							Offset;
	UCHAR							bbpValue;
	UCHAR							bbpID;
	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;	

	pHardwareRegister = (PRT_802_11_HARDWARE_REGISTER) pBuf;

	if (pHardwareRegister->HardwareType == HARDWARE_MAC)
	{
		//Check Offset is valid?
		if (pHardwareRegister->Offset > 0xF4)
			Status = NDIS_STATUS_FAILURE;

		Offset = (USHORT) pHardwareRegister->Offset;
		Value = (ULONG) pHardwareRegister->Data;
		RTUSBWriteMACRegister(pAd, Offset, Value);		
		DBGPRINT(RT_DEBUG_TRACE, "RT_OID_802_11_SET_HARDWARE_REGISTER (MAC offset=0x%08x, data=0x%08x)\n", pHardwareRegister->Offset, pHardwareRegister->Data);

		// 2004-11-08 a special 16-byte on-chip memory is used for RaConfig to pass debugging parameters to driver
		// for debug-tuning only
		if ((pHardwareRegister->Offset >= HW_DEBUG_SETTING_BASE) && 
			(pHardwareRegister->Offset <= HW_DEBUG_SETTING_END))
		{
			// 0x2bf0: test power-saving feature
			if (pHardwareRegister->Offset == HW_DEBUG_SETTING_BASE)
			{
#if 0			
				ULONG isr, imr, gimr;
				USHORT tbtt = 3;

				RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &isr);
				RTMP_IO_READ32(pAd, MCU_INT_MASK_CSR, &imr);
				RTMP_IO_READ32(pAd, INT_MASK_CSR, &gimr);
				DBGPRINT(RT_DEBUG_TRACE, "Sleep %d TBTT, 8051 IMR=%08x, ISR=%08x, MAC IMR=%08x\n", tbtt, imr, isr, gimr);
				AsicSleepThenAutoWakeup(pAd, tbtt);	
#endif				
			}
			// 0x2bf4: test H2M_MAILBOX. byte3: Host command, byte2: token, byte1-0: arguments
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 4))
			{
				// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
				if (pHardwareRegister->Data & 0x000000ff) 
				{
					pAd->BbpTuning.bEnable = TRUE;
					DBGPRINT(RT_DEBUG_TRACE,"turn on R17 tuning\n");
				}
				else
				{
					UCHAR R17;

					pAd->BbpTuning.bEnable = FALSE;
					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
					{
						if (pAd->PortCfg.Channel > 14)
							R17 = pAd->BbpTuning.R17LowerBoundA;
						else
							R17 = pAd->BbpTuning.R17LowerBoundG;
						RTUSBWriteBBPRegister(pAd, 17, R17);
						DBGPRINT(RT_DEBUG_TRACE,"turn off R17 tuning, restore to 0x%02x\n", R17);
					}
				}
			}
			// 0x2bf8: test ACK policy and QOS format in ADHOC mode
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 8))
			{
				PUCHAR pAckStr[4] = {"NORMAL", "NO-ACK", "NO-EXPLICIT-ACK", "BLOCK-ACK"};
				EDCA_PARM DefaultEdcaParm;

				// byte0 b1-0 means ACK POLICY - 0: normal ACK, 1: no ACK, 2:no explicit ACK, 3:BA
				pAd->PortCfg.AckPolicy[0] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[1] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[2] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[3] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				DBGPRINT(RT_DEBUG_TRACE, "ACK policy = %s\n", pAckStr[(UCHAR)pHardwareRegister->Data & 0x02]);

				// any non-ZERO value in byte1 turn on EDCA & QOS format
				if (pHardwareRegister->Data & 0x0000ff00) 
				{
					NdisZeroMemory(&DefaultEdcaParm, sizeof(EDCA_PARM));
					DefaultEdcaParm.bValid = TRUE;
					DefaultEdcaParm.Aifsn[0] = 3;
					DefaultEdcaParm.Aifsn[1] = 7;
					DefaultEdcaParm.Aifsn[2] = 2;
					DefaultEdcaParm.Aifsn[3] = 2;

					DefaultEdcaParm.Cwmin[0] = 4;
					DefaultEdcaParm.Cwmin[1] = 4;
					DefaultEdcaParm.Cwmin[2] = 3;
					DefaultEdcaParm.Cwmin[3] = 2;

					DefaultEdcaParm.Cwmax[0] = 10;
					DefaultEdcaParm.Cwmax[1] = 10;
					DefaultEdcaParm.Cwmax[2] = 4;
					DefaultEdcaParm.Cwmax[3] = 3;

					DefaultEdcaParm.Txop[0]  = 0;
					DefaultEdcaParm.Txop[1]  = 0;
					DefaultEdcaParm.Txop[2]  = 96;
					DefaultEdcaParm.Txop[3]  = 48;
					AsicSetEdcaParm(pAd, &DefaultEdcaParm);
				}
				else
					AsicSetEdcaParm(pAd, NULL);
			}
			// 0x2bfc: turn ON/OFF TX aggregation
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 12))
			{
				if (pHardwareRegister->Data)
					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
				else
					OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
				DBGPRINT(RT_DEBUG_TRACE, "AGGREGATION = %d\n", OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED));
			}
			else
				Status = NDIS_STATUS_FAILURE;				
		}
	}
	else if (pHardwareRegister->HardwareType == HARDWARE_BBP)
	{
		bbpID = (UCHAR) pHardwareRegister->Offset;
		bbpValue = (UCHAR) pHardwareRegister->Data;
		RTUSBWriteBBPRegister(pAd, bbpID, bbpValue);
		DBGPRINT(RT_DEBUG_TRACE, "BBP:ID[0x%02x]=[0x%02x]\n", bbpID, bbpValue);		
	}

	return Status;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -