/* ======================================================================== Routine Description: Initialize Multi-BSS function. Arguments: pAd points to our adapter pDevMain points to the main BSS network interface Return Value: None Note: 1. Only create and initialize virtual network interfaces. 2. No main network interface here. 3. If you down ra0 and modify the BssNum of RT2860AP.dat/RT2870AP.dat, it will not work! You must rmmod rt2860ap.ko and lsmod rt2860ap.ko again. ======================================================================== */ VOID MBSS_Init(RTMP_ADAPTER *pAd, RTMP_OS_NETDEV_OP_HOOK *pNetDevOps) { #define MBSS_MAX_DEV_NUM 32 PNET_DEV pDevNew; INT32 IdBss, MaxNumBss; INT status; RTMP_OS_NETDEV_OP_HOOK netDevHook; /* sanity check to avoid redundant virtual interfaces are created */ if (pAd->FlgMbssInit != FALSE) return; MaxNumBss = pAd->ApCfg.BssidNum; if (MaxNumBss > MAX_MBSSID_NUM(pAd)) MaxNumBss = MAX_MBSSID_NUM(pAd); /* first IdBss must not be 0 (BSS0), must be 1 (BSS1) */ for(IdBss=FIRST_MBSSID; IdBss<MAX_MBSSID_NUM(pAd); IdBss++) pAd->ApCfg.MBSSID[IdBss].wdev.if_dev = NULL; /* create virtual network interface */ for(IdBss=FIRST_MBSSID; IdBss<MaxNumBss; IdBss++) { struct wifi_dev *wdev; UINT32 MC_RowID = 0, IoctlIF = 0; char *dev_name; #ifdef MULTIPLE_CARD_SUPPORT MC_RowID = pAd->MC_RowID; #endif /* MULTIPLE_CARD_SUPPORT */ #ifdef HOSTAPD_SUPPORT IoctlIF = pAd->IoctlIF; #endif /* HOSTAPD_SUPPORT */ dev_name = get_dev_name_prefix(pAd, INT_MBSSID); pDevNew = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_MBSSID, IdBss, sizeof(struct mt_dev_priv), dev_name); #ifdef HOSTAPD_SUPPORT pAd->IoctlIF = IoctlIF; #endif /* HOSTAPD_SUPPORT */ if (pDevNew == NULL) { pAd->ApCfg.BssidNum = IdBss; /* re-assign new MBSS number */ break; } else { DBGPRINT(RT_DEBUG_TRACE, ("Register MBSSID IF (%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); } wdev = &pAd->ApCfg.MBSSID[IdBss].wdev; wdev->wdev_type = WDEV_TYPE_AP; wdev->func_dev = &pAd->ApCfg.MBSSID[IdBss]; wdev->sys_handle = (void *)pAd; wdev->if_dev = pDevNew; if (rtmp_wdev_idx_reg(pAd, wdev) < 0) { DBGPRINT(RT_DEBUG_ERROR, ("Assign wdev idx for %s failed, free net device!\n", RTMP_OS_NETDEV_GET_DEVNAME(pDevNew))); RtmpOSNetDevFree(pDevNew); break; } wdev->tx_pkt_allowed = ApAllowToSendPacket; RTMP_OS_NETDEV_SET_PRIV(pDevNew, pAd); RTMP_OS_NETDEV_SET_WDEV(pDevNew, wdev); /* init operation functions and flags */ NdisCopyMemory(&netDevHook, pNetDevOps, sizeof(netDevHook)); netDevHook.priv_flags = INT_MBSSID; netDevHook.needProtcted = TRUE; netDevHook.wdev = wdev; /* Init MAC address of virtual network interface */ NdisMoveMemory(&netDevHook.devAddr[0], &wdev->bssid[0], MAC_ADDR_LEN); /* register this device to OS */ status = RtmpOSNetDevAttach(pAd->OpMode, pDevNew, &netDevHook); } pAd->FlgMbssInit = TRUE; }
VOID WDS_Init(RTMP_ADAPTER *pAd, RTMP_OS_NETDEV_OP_HOOK *pNetDevOps) { INT index; PNET_DEV pWdsNetDev; /* sanity check to avoid redundant virtual interfaces are created */ if (pAd->flg_wds_init != FALSE) return; for(index = 0; index < MAX_WDS_ENTRY; index++) { UINT32 MC_RowID = 0, IoctlIF = 0; RT_802_11_WDS_ENTRY *wds_entry; struct wifi_dev *wdev; char *dev_name; #ifdef MULTIPLE_CARD_SUPPORT MC_RowID = pAd->MC_RowID; #endif /* MULTIPLE_CARD_SUPPORT */ #ifdef HOSTAPD_SUPPORT IoctlIF = pAd->IoctlIF; #endif /* HOSTAPD_SUPPORT */ dev_name = get_dev_name_prefix(pAd, INT_WDS); pWdsNetDev = RtmpOSNetDevCreate(MC_RowID, &IoctlIF, INT_WDS, index, sizeof(struct mt_dev_priv), dev_name); #ifdef HOSTAPD_SUPPORT pAd->IoctlIF = IoctlIF; #endif /* HOSTAPD_SUPPORT */ wds_entry = &pAd->WdsTab.WdsEntry[index]; wdev = &wds_entry->wdev; if (pWdsNetDev == NULL) { /* allocation fail, exit */ DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (WDS)...\n")); break; } DBGPRINT(RT_DEBUG_TRACE, ("The new WDS interface MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pAd->MacTab.Content[wds_entry->MacTabMatchWCID].Addr))); NdisZeroMemory(&wds_entry->WdsCounter, sizeof(WDS_COUNTER)); wdev->wdev_type = WDEV_TYPE_WDS; wdev->func_dev = wds_entry; wdev->func_idx = index; wdev->sys_handle = (void *)pAd; wdev->if_dev = pWdsNetDev; wdev->tx_pkt_allowed = ApWdsAllowToSendPacket; // TODO: shiang-usw, modify this to WDSSendPacket wdev->tx_pkt_handle = APSendPacket; wdev->wdev_hard_tx = APHardTransmit; wdev->rx_pkt_allowed = ap_rx_pkt_allow; wdev->rx_pkt_foward = wds_rx_foward_handle; wdev->PhyMode = 0xff; wdev->allow_data_tx = TRUE; // let tx_pkt_allowed() to check it! wdev->PortSecured = WPA_802_1X_PORT_SECURED; NdisMoveMemory(&wdev->if_addr[0], &pNetDevOps->devAddr[0], MAC_ADDR_LEN); RTMP_OS_NETDEV_SET_PRIV(pWdsNetDev, pAd); RTMP_OS_NETDEV_SET_WDEV(pWdsNetDev, wdev); if (rtmp_wdev_idx_reg(pAd, wdev) < 0) { DBGPRINT(RT_DEBUG_ERROR, ("Assign wdev idx for %s failed, free net device!\n", RTMP_OS_NETDEV_GET_DEVNAME(pWdsNetDev))); RtmpOSNetDevFree(pWdsNetDev); break; } pNetDevOps->priv_flags = INT_WDS; pNetDevOps->needProtcted = TRUE; pNetDevOps->wdev = wdev; /* Register this device */ RtmpOSNetDevAttach(pAd->OpMode, pWdsNetDev, pNetDevOps); } if (index > 0) pAd->flg_wds_init = TRUE; NdisAllocateSpinLock(pAd, &pAd->WdsTabLock); DBGPRINT(RT_DEBUG_TRACE, ("Total allocated %d WDS interfaces!\n", index)); }