📄 rtmp_main.c
字号:
/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2005, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: rtmp_main.c Abstract: main initialization routines Revision History: Who When What -------- ---------- ---------------------------------------------- Name Date Modification logs Jan Lee 01-10-2005 modified*/#include "rt_config.h"ULONG RTDebugLevel = RT_DEBUG_TRACE;char *hostname = ""; // default CMPC#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)MODULE_PARM (hostname, "s");#elsemodule_param (hostname, charp, 0);#endifMODULE_PARM_DESC (hostname, "Host Name");// Following information will be show when you run 'modinfo'// *** If you have a solution for the bug in current version of driver, please mail to me.// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");MODULE_DESCRIPTION("RT73 Wireless Lan Linux Driver");// *** open source release//MODULE_LICENSE("GPL");/* Kernel thread and vars, which handles packets that are completed. Only * packets that have a "complete" function are sent here. This way, the * completion is run out of kernel context, and doesn't block the rest of * the stack. */static int mlme_kill;static int RTUSBCmd_kill;//static dma_addr_t dma_adapter;extern const struct iw_handler_def rt73_iw_handler_def;/* module table */struct usb_device_id rtusb_usb_id[] = RT73_USB_DEVICES;INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id); MODULE_DEVICE_TABLE(usb, rtusb_usb_id);#ifndef PF_NOFREEZE#define PF_NOFREEZE 0#endifstatic int usb_rtusb_init_device( struct net_device *net_dev);static int usb_rtusb_close_device( IN PRTMP_ADAPTER pAd);/**************************************************************************//**************************************************************************///tested for kernel 2.4 series/**************************************************************************//**************************************************************************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static void usb_rtusb_disconnect(struct usb_device *dev, void *ptr);static void *usb_rtusb_probe(struct usb_device *dev, UINT interface, const struct usb_device_id *id_table);struct usb_driver rtusb_driver = { name:"rt73", probe:usb_rtusb_probe, disconnect:usb_rtusb_disconnect, id_table:rtusb_usb_id, };#else/**************************************************************************//**************************************************************************///tested for kernel 2.6series/**************************************************************************//**************************************************************************/static int usb_rtusb_probe (struct usb_interface *intf, const struct usb_device_id *id);static void usb_rtusb_disconnect(struct usb_interface *intf);#ifdef CONFIG_PMstatic int rt73_suspend(struct usb_interface *intf, pm_message_t state);static int rt73_resume(struct usb_interface *intf);#endifstruct usb_driver rtusb_driver = {#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) .owner = THIS_MODULE,#endif .name="rt73", .probe=usb_rtusb_probe, .disconnect=usb_rtusb_disconnect, .id_table=rtusb_usb_id,#ifdef CONFIG_PM .suspend = rt73_suspend, .resume = rt73_resume,#endif };/************************** Add for ethtool support. HAL/NetworkManager will use it.***************************/#define CSR_REG_BASE MAC_CSR0#define CSR_REG_SIZE 0x04b0#define EEPROM_BASE 0x0000#define EEPROM_SIZE 0x0100#ifdef CONFIG_PMstatic int rt73_suspend(struct usb_interface *intf, pm_message_t state){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; DBGPRINT(RT_DEBUG_TRACE,"---> rt73_suspend()\n"); pAd = usb_get_intfdata(intf); // need to send it first before USB go susped. // without it system unable to reume back. RTUSB_VendorRequest(pAd, 0, DEVICE_VENDOR_REQUEST_OUT, 0x0C, 0x0, 0x0, NULL, 0); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); MlmeRadioOff(pAd); DBGPRINT(RT_DEBUG_TRACE,"<--- rt73_suspend()\n"); return 0;}static intrt73_resume(struct usb_interface *intf){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; DBGPRINT(RT_DEBUG_TRACE,"---> rt73_resume()\n"); pAd = usb_get_intfdata(intf); MlmeRadioOn(pAd); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); DBGPRINT(RT_DEBUG_TRACE,"<--- rt73_resume()\n"); return 0;}#endifstatic voidrt73_get_drvinfo(struct net_device *net_dev, struct ethtool_drvinfo *drvinfo){ PRTMP_ADAPTER pAd = net_dev->priv; strcpy(drvinfo->driver, NIC_DEVICE_NAME); strcpy(drvinfo->version, DRIVER_VERSION); snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d(%d)", pAd->FirmwareVersion, pAd->EepromVersion); usb_make_path(pAd->pUsb_Dev, drvinfo->bus_info, sizeof(drvinfo->bus_info));}static intrt73_get_regs_len(struct net_device *net_dev){ return CSR_REG_SIZE;}static voidrt73_get_regs(struct net_device *net_dev, struct ethtool_regs *regs, void *data){ PRTMP_ADAPTER pAd = net_dev->priv; unsigned int counter; regs->len = CSR_REG_SIZE; for (counter = 0; counter < CSR_REG_SIZE; counter += sizeof(UINT32)) { RTUSBReadMACRegister(pAd, CSR_REG_BASE + counter, (PULONG)data); data += sizeof(UINT32); }}static uint32 rt73_ethtool_get_link(struct net_device *dev){ RTMP_ADAPTER *pAd; ASSERT((dev)); pAd = (PRTMP_ADAPTER) dev->priv; //We return true if we already associated to some AP. return(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED));}static intrt73_get_eeprom_len(struct net_device *net_dev){ return EEPROM_SIZE;}static intrt73_get_eeprom(struct net_device *net_dev, struct ethtool_eeprom *eeprom, u8 *data){ PRTMP_ADAPTER pAd = net_dev->priv; unsigned int counter; for (counter = eeprom->offset; counter < eeprom->len; counter += sizeof(USHORT)) { USHORT value = 0; RTUSBReadEEPROM(pAd, CSR_REG_BASE + counter, (PUCHAR)&value, sizeof(USHORT)); memcpy(data, &value, sizeof(USHORT)); data += sizeof(USHORT); } return 0;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)struct ethtool_ops rt73_ethtool_ops = {#elsestatic const struct ethtool_ops rt73_ethtool_ops = {#endif .get_drvinfo = rt73_get_drvinfo, .get_regs_len = rt73_get_regs_len, .get_regs = rt73_get_regs, .get_link = rt73_ethtool_get_link, .get_eeprom_len = rt73_get_eeprom_len, .get_eeprom = rt73_get_eeprom,};#endifstruct net_device_stats *rt73_get_ether_stats( IN struct net_device *net_dev){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv; DBGPRINT(RT_DEBUG_INFO, "rt73_get_ether_stats --->\n"); pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.vv.LowPart; // total packets received pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart; // total packets transmitted pAd->stats.rx_bytes= pAd->RalinkCounters.ReceivedByteCount; // total bytes received pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount; // total bytes transmitted pAd->stats.rx_errors = pAd->Counters8023.RxErrors; // bad packets received pAd->stats.tx_errors = pAd->Counters8023.TxErrors; // packet transmit problems pAd->stats.rx_dropped = pAd->Counters8023.RxNoBuffer; // no space in linux buffers pAd->stats.tx_dropped = pAd->WlanCounters.FailedCount.vv.LowPart; // no space available in linux pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.vv.LowPart; // multicast packets received pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets pAd->stats.rx_length_errors = 0; pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun pAd->stats.rx_missed_errors = 0; // receiver missed packet // detailed tx_errors pAd->stats.tx_aborted_errors = 0; pAd->stats.tx_carrier_errors = 0; pAd->stats.tx_fifo_errors = 0; pAd->stats.tx_heartbeat_errors = 0; pAd->stats.tx_window_errors = 0; // for cslip etc pAd->stats.rx_compressed = 0; pAd->stats.tx_compressed = 0; return &pAd->stats;}#if (WIRELESS_EXT >= 12)/* ======================================================================== Routine Description: get wireless statistics Arguments: net_dev Pointer to net_device Return Value: struct iw_statistics Note: This function will be called when query /proc ========================================================================*/long rt_abs(long arg) { return (arg<0)? -arg : arg;}struct iw_statistics *rt73_get_wireless_stats( IN struct net_device *net_dev){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv; DBGPRINT(RT_DEBUG_TRACE, "rt73_get_wireless_stats --->\n"); // TODO: All elements are zero before be implemented pAd->iw_stats.status = 0; // Status - device dependent for now pAd->iw_stats.qual.qual = pAd->Mlme.ChannelQuality; // link quality (%retries, SNR, %missed beacons or better...)#ifdef RTMP_EMBEDDED pAd->iw_stats.qual.level = rt_abs(pAd->PortCfg.LastRssi); // signal level (dBm)#else pAd->iw_stats.qual.level = abs(pAd->PortCfg.LastRssi); // signal level (dBm)#endif pAd->iw_stats.qual.level += 256 - pAd->BbpRssiToDbmDelta; pAd->iw_stats.qual.noise = (pAd->BbpWriteLatch[17] > pAd->BbpTuning.R17UpperBoundG) ? pAd->BbpTuning.R17UpperBoundG : ((ULONG) pAd->BbpWriteLatch[17]); // noise level (dBm) pAd->iw_stats.qual.noise += 256 - 143; pAd->iw_stats.qual.updated = 1; // Flags to know if updated pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe // pAd->iw_stats.discard.code, discard.fragment, discard.retries, discard.misc has counted in other place return &pAd->iw_stats;}#endifVOID RTUSBHalt( IN PRTMP_ADAPTER pAd, IN BOOLEAN IsFree){ BOOLEAN TimerCancelled; DBGPRINT(RT_DEBUG_TRACE, "====> RTUSBHalt\n"); // // before set flag fRTMP_ADAPTER_HALT_IN_PROGRESS, // we should send a disassoc frame to our AP. // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); RTMPCancelTimer(&pAd->PortCfg.QuickResponeForRateUpTimer,&TimerCancelled); RTMPCancelTimer(&pAd->RxAnt.RxAntDiversityTimer,&TimerCancelled); // Free MLME stuff MlmeHalt(pAd); // Sleep 50 milliseconds so pending io might finish normally RTMPusecDelay(50000); // We want to wait until all pending receives and sends to the // device object. We cancel any // irps. Wait until sends and receives have stopped. // RTUSBCancelPendingIRPs(pAd); // Free the entire adapter object ReleaseAdapter(pAd, IsFree, FALSE); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);}static int usb_rtusb_close_device( IN PRTMP_ADAPTER pAd){ int i = 0; int ret; DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); DBGPRINT(RT_DEBUG_TRACE, "-->usb_rtusb_close_device \n"); // ensure there are no more active urbs. add_wait_queue (&unlink_wakeup, &wait); pAd->wait = &unlink_wakeup; // maybe wait for deletions to finish. while ((i < 25) && atomic_read(&pAd->PendingRx) > 0) {#if LINUX_VERSION_CODE >KERNEL_VERSION(2,6,9) msleep(UNLINK_TIMEOUT_MS);#endif i++; } pAd->wait = NULL; remove_wait_queue (&unlink_wakeup, &wait); if (pAd->MLMEThr_pid >= 0) { mlme_kill = 1; RTUSBMlmeUp(pAd); wmb(); // need to check ret = kill_proc (pAd->MLMEThr_pid, SIGTERM, 1); if (ret) { printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d\n", pAd->net_dev->name, pAd->MLMEThr_pid); } wait_for_completion (&pAd->MlmeThreadNotify); // reset mlme thread pAd->MLMEThr_pid = -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -