📄 rtmp_main.c
字号:
{
if (cmdqelmt->buffer != NULL)
kfree(cmdqelmt->buffer);
}
kfree((PCmdQElmt)cmdqelmt);
}
else
cmdqelmt->InUse = FALSE;
}
}
static int usb_rtusb_open(struct net_device *net_dev)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UCHAR TmpPhy;
printk("rt73 driver version - %s\n", DRIVER_VERSION);
init_MUTEX(&(pAd->usbdev_semaphore));
// init mediastate to disconnected
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
pAd->rx_bh.func = RTUSBRxPacket;
// Initialize pAd->PortCfg to manufacture default
PortCfgInit(pAd);
// Init RTMP_ADAPTER CmdQElements
Status = RTMPInitAdapterBlock(pAd);
if (Status != NDIS_STATUS_SUCCESS)
{
return Status;
}
//
// Init send data structures and related parameters
//
Status = NICInitTransmit(pAd);
if (Status != NDIS_STATUS_SUCCESS)
{
return Status;
}
//
// Init receive data structures and related parameters
//
Status = NICInitRecv(pAd);
if (Status != NDIS_STATUS_SUCCESS)
{
goto out;
}
// Wait for hardware stable
{
ULONG MacCsr0 = 0, Index = 0;
do
{
Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacCsr0);
if (MacCsr0 != 0)
break;
RTMPusecDelay(1000);
} while (Index++ < 1000);
DBGPRINT(RT_DEBUG_TRACE, "Init: MAC_CSR0=0x%08x, Status=0x%08x\n", MacCsr0, Status);
}
// Load 8051 firmware
Status = NICLoadFirmware(pAd);
if(Status != NDIS_STATUS_SUCCESS)
{
goto out;
}
// Initialize Asics
NICInitializeAsic(pAd);
// Read RaConfig profile parameters
#ifdef READ_PROFILE_FROM_FILE
RTMPReadParametersFromFile(pAd);
#endif
//
// Read additional info from NIC such as MAC address
// This function must called after register CSR base address
//
#ifdef INIT_FROM_EEPROM
NICReadEEPROMParameters(pAd);
NICInitAsicFromEEPROM(pAd);
#endif
RTUSBWriteHWMACAddress(pAd);
// external LNA has different R17 base
if (pAd->NicConfig2.field.ExternalLNA)
{
pAd->BbpTuning.R17LowerBoundA += 0x10;
pAd->BbpTuning.R17UpperBoundA += 0x10;
pAd->BbpTuning.R17LowerBoundG += 0x10;
pAd->BbpTuning.R17UpperBoundG += 0x10;
}
// hardware initialization after all parameters are acquired from
// Registry or E2PROM
TmpPhy = pAd->PortCfg.PhyMode;
pAd->PortCfg.PhyMode = 0xff;
RTMPSetPhyMode(pAd, TmpPhy);
//
// initialize MLME
//
Status = MlmeInit(pAd);
if(Status != NDIS_STATUS_SUCCESS)
{
goto out;
}
// mlmethread & RTUSBCmd flag restart
mlme_kill = 0;
RTUSBCmd_kill =0;
CreateThreads(net_dev);
// at every open handler, copy mac address.
memcpy(pAd->net_dev->dev_addr, pAd->CurrentAddress, pAd->net_dev->addr_len);
// Clear Reset Flag before starting receiving/transmitting
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
{
RTUSBBulkReceive(pAd);
RTUSBWriteMACRegister(pAd, TXRX_CSR0, 0x025eb032); // enable RX of MAC block, Staion not drop control frame
// Initialize RF register to default value
AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
AsicLockChannel(pAd, pAd->PortCfg.Channel);
}
// USB_ID info for UI
pAd->VendorDesc = 0x148F2573;
// Start net_dev interface tx /rx
netif_start_queue(net_dev);
netif_carrier_on(net_dev);
netif_wake_queue(net_dev);
return 0;
out:
ReleaseAdapter(pAd, TRUE, FALSE);
return 0;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int usb_rtusb_close(struct net_device *net_dev)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
int ret;
int i = 0;
DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
DECLARE_WAITQUEUE (wait, current);
DBGPRINT(RT_DEBUG_TRACE,"-->rt73_close\n");
netif_carrier_off(pAd->net_dev);
netif_stop_queue(pAd->net_dev);
DBGPRINT(RT_DEBUG_INFO,"Ensure there are no more active urbs \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 < 10) && atomic_read(&pAd->PendingRx) > 0) {
//msleep(UNLINK_TIMEOUT_MS);
i++;
DBGPRINT (RT_DEBUG_INFO,"waited for %d urb to complete\n", atomic_read(&pAd->PendingRx));
}
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_ERR "%s: unable to signal thread\n", pAd->net_dev->name);
return ret;
}
wait_for_completion (&pAd->notify);
}
if (pAd->RTUSBCmdThr_pid>= 0)
{
RTUSBCmd_kill = 1;
RTUSBCMDUp(pAd);
wmb(); // need to check
ret = kill_proc (pAd->RTUSBCmdThr_pid, SIGTERM, 1);
if (ret)
{
printk (KERN_ERR "%s: unable to signal thread\n", pAd->net_dev->name);
return ret;
}
wait_for_completion (&pAd->notify);
}
RTUSBHalt(pAd, TRUE);
DBGPRINT(RT_DEBUG_TRACE,"<--rt73_close\n");
return 0;
}
INT MlmeThread(
IN void * Context)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
daemonize();
current->flags |= PF_NOFREEZE;
/* signal that we've started the thread */
complete(&(pAd->notify));
#if 1
while (1)
{
//if(down_interruptible(&pAd->mlme_semaphore))
//break;
/* lock the device pointers */
down(&(pAd->mlme_semaphore));
if (mlme_kill)
break;
/* lock the device pointers , need to check if required*/
down(&(pAd->usbdev_semaphore));
MlmeHandler(pAd);
/* unlock the device pointers */
up(&(pAd->usbdev_semaphore));
}
#else
// I tried this way for thread handling
while(1)
{
timeout = next_tick;
do {
timeout = interruptible_sleep_on_timeout (&pAd->MLMEThr_wait, timeout);
/* make swsusp happy with our thread */
if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE);
DBGPRINT(RT_DEBUG_TRACE, "current->flags = 0x%x\n",current->flags );
} while (!signal_pending (current) && (timeout > 0));
if (signal_pending (current)) {
flush_signals(current);
}
if (mlme_kill)
break;
}
#endif
/* notify the exit routine that we're actually exiting now
*
* complete()/wait_for_completion() is similar to up()/down(),
* except that complete() is safe in the case where the structure
* is getting deleted in a parallel mode of execution (i.e. just
* after the down() -- that's necessary for the thread-shutdown
* case.
*
* complete_and_exit() goes even further than this -- it is safe in
* the case that the thread of the caller is going away (not just
* the structure) -- this is necessary for the module-remove case.
* This is important in preemption kernels, which transfer the flow
* of execution immediately upon a complete().
*/
complete_and_exit (&pAd->notify, 0);
DBGPRINT(RT_DEBUG_TRACE, "<---MlmeThread\n");
}
INT RTUSBCmdThread(
IN void * Context)
{
aslkd;askdf
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
daemonize();
current->flags |= PF_NOFREEZE;
/* signal that we've started the thread */
complete(&(pAd->notify));
while (1)
{
//if(down_interruptible(&pAd->mlme_semaphore))
//break;
/* lock the device pointers */
down(&(pAd->RTUSBCmd_semaphore));
if (RTUSBCmd_kill)
break;
/* lock the device pointers , need to check if required*/
down(&(pAd->usbdev_semaphore));
CMDHandler(pAd);
/* unlock the device pointers */
up(&(pAd->usbdev_semaphore));
}
/* notify the exit routine that we're actually exiting now
*
* complete()/wait_for_completion() is similar to up()/down(),
* except that complete() is safe in the case where the structure
* is getting deleted in a parallel mode of execution (i.e. just
* after the down() -- that's necessary for the thread-shutdown
* case.
*
* complete_and_exit() goes even further than this -- it is safe in
* the case that the thread of the caller is going away (not just
* the structure) -- this is necessary for the module-remove case.
* This is important in preemption kernels, which transfer the flow
* of execution immediately upon a complete().
*/
complete_and_exit (&pAd->notify, 0);
DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");
}
static void *usb_rtusb_probe(struct usb_device *dev, UINT interface,
const struct usb_device_id *id_table)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
int i;
struct net_device *netdev;
int res = -ENOMEM;
for (i = 0; i < rtusb_usb_id_len; i++)
{
if (dev->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
dev->descriptor.idProduct == rtusb_usb_id[i].idProduct)
{
printk("idVendor = 0x%x, idProduct = 0x%x \n",dev->descriptor.idVendor, dev->descriptor.idProduct);
break;
}
}
if (i == rtusb_usb_id_len) {
printk("Device Descriptor not matching\n");
return NULL;
}
netdev = alloc_etherdev(sizeof (*pAd));
if(!netdev)
{
printk("alloc_etherdev failed\n");
MOD_DEC_USE_COUNT;
usb_dec_dev_use(dev);
return NULL;
}
pAd = netdev->priv;
pAd->net_dev = netdev;
netif_stop_queue(netdev);
pAd->config = dev->config;
pAd->pUsb_Dev= dev;
SET_MODULE_OWNER(pAd->net_dev);
ether_setup(pAd->net_dev);
netdev->open = usb_rtusb_open;
netdev->hard_start_xmit = RTMPSendPackets;
netdev->stop = usb_rtusb_close;
netdev->priv = pAd;
netdev->get_stats = rt73_get_ether_stats;
#if WIRELESS_EXT >= 11
netdev->get_wireless_stats = rt73_get_wireless_stats;
netdev->wireless_handlers = (struct iw_handler_def *) &rt73_iw_handler_def;
#endif
netdev->do_ioctl = rt73_ioctl;
pAd->net_dev->hard_header_len = 14;
pAd->net_dev->mtu = 1500;
pAd->net_dev->addr_len = 6;
pAd->net_dev->weight = 64;
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
{// find available
int i=0;
char slot_name[IFNAMSIZ];
struct net_device *device;
struct usb_interface *ifp= &dev->actconfig->interface[interface]; // get interface from system
struct usb_interface_descriptor *as;
struct usb_endpoint_descriptor *ep;
for (i = 0; i < 8; i++)
{
sprintf(slot_name, "rausb%d", i);
read_lock_bh(&dev_base_lock); // avoid multiple init
for (device = dev_base; device != NULL; device = device->next)
{
if (strncmp(device->name, slot_name, 4) == 0)
{
break;
}
}
read_unlock_bh(&dev_base_lock);
if(device == NULL) break;
}
if(i == 8)
{
DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n");
return NULL;
}
sprintf(pAd->net_dev->name, "rausb%d", i);
DBGPRINT(RT_DEBUG_ERROR, "usb device name %s\n",pAd->net_dev->name);
/* get Max Packet Size from usb_dev endpoint */
// ifp = dev->actconfig->interface + i;
as = ifp->altsetting + ifp->act_altsetting;
ep = as->endpoint;
pAd->BulkOutMaxPacketSize = (USHORT)ep[i].wMaxPacketSize;
DBGPRINT(RT_DEBUG_TRACE, "BulkOutMaxPacketSize %d\n", pAd->BulkOutMaxPacketSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -