在rt2860_probe
函数中调用了RtmpPhyNetDevInit
为无线网络设备进行初始化,实质是分配建立了pNetDevHook结构体:
PNET_DEV RtmpPhyNetDevInit(
IN VOID *pAd,
IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
{
struct net_device *net_dev = NULL;
/* NDIS_STATUS Status; */
ULONG InfId, OpMode;
RTMP_DRIVER_MAIN_INF_GET(pAd, &InfId);
/* net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME); */
RTMP_DRIVER_MAIN_INF_CREATE(pAd, &net_dev);
if (net_dev == NULL)
{
printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
return NULL;
}
NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
pNetDevHook->open = MainVirtualIF_open;
pNetDevHook->stop = MainVirtualIF_close;
pNetDevHook->xmit = rt28xx_send_packets;
#ifdef IKANOS_VX_1X0
pNetDevHook->xmit = IKANOS_DataFramesTx;
#endif /* IKANOS_VX_1X0 */
pNetDevHook->ioctl = rt28xx_ioctl;
pNetDevHook->priv_flags = InfId; /*INT_MAIN; */
pNetDevHook->get_stats = RT28xx_get_ether_stats;
pNetDevHook->needProtcted = FALSE;
#if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
pNetDevHook->get_wstats = rt28xx_get_wireless_stats;
#endif
RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode);
#ifdef CONFIG_STA_SUPPORT
#if WIRELESS_EXT >= 12
if (OpMode == OPMODE_STA)
{
pNetDevHook->iw_handler = (void *)&rt28xx_iw_handler_def;
}
#endif /*WIRELESS_EXT >= 12 */
#endif /* CONFIG_STA_SUPPORT */
#ifdef CONFIG_APSTA_MIXED_SUPPORT
#if WIRELESS_EXT >= 12
if (OpMode == OPMODE_AP)
{
pNetDevHook->iw_handler = &rt28xx_ap_iw_handler_def;
}
#endif /*WIRELESS_EXT >= 12 */
#endif /* CONFIG_APSTA_MIXED_SUPPORT */
/* put private data structure */
RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
/* double-check if pAd is associated with the net_dev */
if (RTMP_OS_NETDEV_GET_PRIV(net_dev) == NULL)
{
RtmpOSNetDevFree(net_dev);
return NULL;
}
/* pAd->net_dev = net_dev; */
RTMP_DRIVER_NET_DEV_SET(pAd, net_dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
SET_MODULE_OWNER(net_dev);
#endif
return net_dev;
}
pNetDevHook
是RTMP_OS_NETDEV_OP_HOOK
结构体,这个结构体是RTMP_OS为对网络设备进行操作的hook,并在RtmpOSNetDevAttach
函数中与分配net_device
结构体pNetDev进行了关联。则网络操作open函数即为MainVirtualIF_open
,其他操作也一一对应,MainVirtualIF_open
内容如下:
/*
========================================================================
Routine Description:
Open raxx interface.
Arguments:
*net_dev the raxx interface pointer
========================================================================
*/
int MainVirtualIF_open(IN struct net_device *net_dev)
{
VOID *pAd = NULL;
GET_PAD_FROM_NET_DEV(pAd, net_dev);
/* Sanity check for pAd */
if (pAd == NULL)
return 0; /* close ok */
#ifdef CONFIG_AP_SUPPORT
/* pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE; */
RTMP_DRIVER_AP_MAIN_OPEN(pAd);
#endif /* CONFIG_AP_SUPPORT */
#ifdef IFUP_IN_PROBE
while (RTMP_DRIVER_IOCTL_SANITY_CHECK(pAd, NULL) != NDIS_STATUS_SUCCESS)
{
OS_WAIT(10);
DBGPRINT(RT_DEBUG_TRACE, ("Card not ready, NDIS_STATUS_SUCCESS!\n"));
}
#else
if (VIRTUAL_IF_UP(pAd) != 0)
return -1;
#endif /* IFUP_IN_PROBE */
/* increase MODULE use count */
RT_MOD_INC_USE_COUNT();
netif_start_queue(net_dev);
netif_carrier_on(net_dev);
netif_wake_queue(net_dev);
return 0;
}
在前缀为RTMP_DRIVD
的函数中,例如RTMP_DRIVER_MAIN_INF_GET
和RTMP_DRIVER_MAIN_INF_CREATE
,这些函数都定义了RTMP中的端口Ioctl操作,统一调用了RTMP_COM_IoctlHandle
,并根据参数cmd来选择不同的操作任务。
RTMP_COM_IoctlHandle
函数内容如下:
INT RTMP_COM_IoctlHandle(
IN VOID *pAdSrc,
IN RTMP_IOCTL_INPUT_STRUCT *wrq,
IN INT cmd,
IN USHORT subcmd,
IN VOID *pData,
IN ULONG Data)
{
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc;
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
INT Status = NDIS_STATUS_SUCCESS, i;
UCHAR PermanentAddress[MAC_ADDR_LEN];
USHORT Addr01, Addr23, Addr45;
pObj = pObj; /* avoid compile warning */
switch(cmd)
{
case CMD_RTPRIV_IOCTL_NETDEV_GET:
/* get main net_dev */
{
VOID **ppNetDev = (VOID **)pData;
*ppNetDev = (VOID *)(pAd->net_dev);
}
break;
case CMD_RTPRIV_IOCTL_NETDEV_SET:
/* set main net_dev */
pAd->net_dev = pData;
#ifdef CONFIG_AP_SUPPORT
pAd->ApCfg.MBSSID[MAIN_MBSSID].MSSIDDev = pData;
#