void rtw_hal_set_odm_var(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) { struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv; switch (eVariable) { case HAL_ODM_STA_INFO: { struct sta_info *psta = pValue1; if (bSet) { DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); ODM_RAInfo_Init(podmpriv, psta->mac_id); } else { DBG_88E("### Clean STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL); } } break; case HAL_ODM_P2P_STATE: podmpriv->bWIFI_Direct = bSet; break; case HAL_ODM_WIFI_DISPLAY_STATE: podmpriv->bWIFI_Display = bSet; break; default: break; } }
/* * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most * @param path the path of the file to open and read * @param buf the starting address of the buffer to store file content * @param sz how many bytes to read at most * @return the byte we've read, or Linux specific error code */ static int retriveFromFile(char *path, u8 __user *buf, u32 sz) { int ret =-1; mm_segment_t oldfs; struct file *fp; if (path && buf) { if ( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){ DBG_88E("%s openFile path:%s fp=%p\n",__func__, path ,fp); oldfs = get_fs(); set_fs(get_ds()); ret=readFile(fp, buf, sz); set_fs(oldfs); closeFile(fp); DBG_88E("%s readFile, ret:%d\n",__func__, ret); } else { DBG_88E("%s openFile path:%s Fail, ret:%d\n",__func__, path, ret); } } else { DBG_88E("%s NULL pointer\n",__func__); ret = -EINVAL; } return ret; }
u8 sreset_get_wifi_status(struct adapter *padapter) { struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); struct sreset_priv *psrtpriv = &pHalData->srestpriv; u8 status = WIFI_STATUS_SUCCESS; u32 val32 = 0; val32 = usb_read32(padapter, REG_TXDMA_STATUS); if (val32 == 0xeaeaeaea) { psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST; } else if (val32 != 0) { DBG_88E("txdmastatu(%x)\n", val32); psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR; } if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) { DBG_88E("==>%s error_status(0x%x)\n", __func__, psrtpriv->Wifi_Error_Status); status = psrtpriv->Wifi_Error_Status & (~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL)); } DBG_88E("==> %s wifi_status(0x%x)\n", __func__, status); /* status restore */ psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; return status; }
static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) { struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); struct odm_dm_struct *podmpriv = &pHalData->odmpriv; switch (eVariable) { case HAL_ODM_STA_INFO: { struct sta_info *psta = pValue1; if (bSet) { DBG_88E("### Set STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta); ODM_RAInfo_Init(podmpriv, psta->mac_id); } else { DBG_88E("### Clean STA_(%d) info\n", psta->mac_id); ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL); } } break; case HAL_ODM_P2P_STATE: ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet); break; case HAL_ODM_WIFI_DISPLAY_STATE: ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet); break; default: break; } }
struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter) { struct xmit_frame *xmit_frame; struct xmit_buf *xmitbuf; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); xmit_frame = rtw_alloc_xmitframe(pxmitpriv); if (xmit_frame == NULL) { DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__); goto exit; } xmitbuf = rtw_alloc_xmitbuf(pxmitpriv); if (xmitbuf == NULL) { DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__); rtw_free_xmitframe(pxmitpriv, xmit_frame); xmit_frame = NULL; goto exit; } xmit_frame->frame_tag = MGNT_FRAMETAG; xmit_frame->pxmitbuf = xmitbuf; xmit_frame->buf_addr = xmitbuf->pbuf; xmitbuf->priv_data = xmit_frame; pattrib = &xmit_frame->attrib; update_mgntframe_attrib(adapter, pattrib); pattrib->qsel = 0x10;/* Beacon */ pattrib->subtype = WIFI_BEACON; pattrib->pktlen = 0; pattrib->last_txcmdsz = 0; exit: return xmit_frame; }
int proc_set_read_reg(struct file *file, const char __user *buffer, unsigned long count, void *data) { char tmp[16]; u32 addr, len; if (count < 2) { DBG_88E("argument size is less than 2\n"); return -EFAULT; } if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { int num = sscanf(tmp, "%x %x", &addr, &len); if (num != 2) { DBG_88E("invalid read_reg parameter!\n"); return count; } proc_get_read_addr = addr; proc_get_read_len = len; } return count; }
/* * Return: * 0: Leave OK * -1: Timeout * -2: Other error */ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) { unsigned long start_time; u8 bAwake = false; s32 err = 0; start_time = jiffies; while (1) { rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); if (bAwake) break; if (padapter->bSurpriseRemoved) { err = -2; DBG_88E("%s: device surprise removed!!\n", __func__); break; } if (jiffies_to_msecs(jiffies - start_time) > delay_ms) { err = -1; DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms); break; } msleep(1); } return err; }
/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both */ static void rtw_dev_remove(struct usb_interface *pusb_intf) { struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); struct adapter *padapter = dvobj->if1; DBG_88E("+rtw_dev_remove\n"); RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n")); if (!pusb_intf->unregistering) padapter->bSurpriseRemoved = true; rtw_pm_set_ips(padapter, IPS_NONE); rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); LeaveAllPowerSaveMode(padapter); rtw_usb_if1_deinit(padapter); usb_dvobj_deinit(pusb_intf); RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-dev_remove()\n")); DBG_88E("-r871xu_dev_remove, done\n"); return; }
static int ips_netdrv_open(struct adapter *padapter) { int status = _SUCCESS; padapter->net_closed = false; DBG_88E("===> %s.........\n", __func__); padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; status = rtw_hal_init(padapter); if (status == _FAIL) { RT_TRACE(_module_os_intfs_c_, _drv_err_, ("ips_netdrv_open(): Can't init h/w!\n")); goto netdev_open_error; } if (padapter->intf_start) padapter->intf_start(padapter); rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 5000); return _SUCCESS; netdev_open_error: DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup); return _FAIL; }
int proc_set_rx_signal(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct net_device *dev = (struct net_device *)data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 is_signal_dbg; s32 signal_strength; if (count < 1) return -EFAULT; if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); is_signal_dbg = is_signal_dbg == 0 ? 0 : 1; if (is_signal_dbg && num != 2) return count; signal_strength = signal_strength > 100 ? 100 : signal_strength; signal_strength = signal_strength < 0 ? 0 : signal_strength; padapter->recvpriv.is_signal_dbg = is_signal_dbg; padapter->recvpriv.signal_strength_dbg = signal_strength; if (is_signal_dbg) DBG_88E("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); else DBG_88E("set %s\n", "HW_SIGNAL_STRENGTH"); } return count; }
void rtl8188eu_free_recv_priv(struct adapter *padapter) { int i; struct recv_buf *precvbuf; struct recv_priv *precvpriv = &padapter->recvpriv; precvbuf = (struct recv_buf *)precvpriv->precv_buf; for (i = 0; i < NR_RECVBUFF; i++) { usb_free_urb(precvbuf->purb); precvbuf++; } kfree(precvpriv->pallocated_recv_buf); if (skb_queue_len(&precvpriv->rx_skb_queue)) DBG_88E(KERN_WARNING "rx_skb_queue not empty\n"); skb_queue_purge(&precvpriv->rx_skb_queue); if (skb_queue_len(&precvpriv->free_recv_skb_queue)) DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue)); skb_queue_purge(&precvpriv->free_recv_skb_queue); }
void rtl8188e_sreset_xmit_status_check(struct adapter *padapter) { struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); struct sreset_priv *psrtpriv = &pHalData->srestpriv; unsigned long current_time; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; unsigned int diff_time; u32 txdma_status; txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS); if (txdma_status != 0x00) { DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status); rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status); rtl8188e_silentreset_for_specific_platform(padapter); } /* total xmit irp = 4 */ current_time = jiffies; if (0 == pxmitpriv->free_xmitbuf_cnt) { diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_time); if (diff_time > 2000) { if (psrtpriv->last_tx_complete_time == 0) { psrtpriv->last_tx_complete_time = current_time; } else { diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_complete_time); if (diff_time > 4000) { DBG_88E("%s tx hang\n", __func__); rtl8188e_silentreset_for_specific_platform(padapter); } } } } }
/* * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file * @param path the path of the file to open and write * @param buf the starting address of the data to write into file * @param sz how many bytes to write at most * @return the byte we've written, or Linux specific error code */ static int storetofile(char *path, u8 __user *buf, u32 sz) { int ret = 0; mm_segment_t oldfs; struct file *fp; if (path && buf) { ret = openfile(&fp, path, O_CREAT|O_WRONLY, 0666); if (0 == ret) { DBG_88E("%s openfile path:%s fp =%p\n", __func__, path, fp); oldfs = get_fs(); set_fs(get_ds()); ret = writefile(fp, buf, sz); set_fs(oldfs); closefile(fp); DBG_88E("%s writefile, ret:%d\n", __func__, ret); } else { DBG_88E("%s openfile path:%s Fail, ret:%d\n", __func__, path, ret); } } else { DBG_88E("%s NULL pointer\n", __func__); ret = -EINVAL; } return ret; }
void rtw_macaddr_cfg(u8 *mac_addr) { u8 mac[ETH_ALEN]; if (mac_addr == NULL) return; if (rtw_initmac && mac_pton(rtw_initmac, mac)) { /* Users specify the mac address */ memcpy(mac_addr, mac, ETH_ALEN); } else { /* Use the mac address stored in the Efuse */ memcpy(mac, mac_addr, ETH_ALEN); } if (((mac[0] == 0xff) && (mac[1] == 0xff) && (mac[2] == 0xff) && (mac[3] == 0xff) && (mac[4] == 0xff) && (mac[5] == 0xff)) || ((mac[0] == 0x0) && (mac[1] == 0x0) && (mac[2] == 0x0) && (mac[3] == 0x0) && (mac[4] == 0x0) && (mac[5] == 0x0))) { mac[0] = 0x00; mac[1] = 0xe0; mac[2] = 0x4c; mac[3] = 0x87; mac[4] = 0x00; mac[5] = 0x00; /* use default mac address */ memcpy(mac_addr, mac, ETH_ALEN); DBG_88E("MAC Address from efuse error, assign default one !!!\n"); } DBG_88E("rtw_macaddr_cfg MAC Address = %pM\n", (mac_addr)); }
static void update_hw_ht_param(struct adapter *padapter) { unsigned char max_AMPDU_len; unsigned char min_MPDU_spacing; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; DBG_88E("%s\n", __func__); /* handle A-MPDU parameter field */ /* ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k ampdu_params_info [4:2]:Min MPDU Start Spacing */ max_AMPDU_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03; min_MPDU_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2; rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); /* */ /* Config SM Power Save setting */ /* */ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & 0x0C) >> 2; if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__); }
int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr) { struct list_head *plist, *phead; struct rtw_wlan_acl_node *paclnode; struct sta_priv *pstapriv = &padapter->stapriv; struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; struct __queue *pacl_node_q = &pacl_list->acl_node_q; DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr)); spin_lock_bh(&pacl_node_q->lock); phead = get_list_head(pacl_node_q); plist = phead->next; while (phead != plist) { paclnode = container_of(plist, struct rtw_wlan_acl_node, list); plist = plist->next; if (!memcmp(paclnode->addr, addr, ETH_ALEN)) { if (paclnode->valid) { paclnode->valid = false; list_del_init(&paclnode->list); pacl_list->num--; } } } spin_unlock_bh(&pacl_node_q->lock); DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num); return 0; }
static void rtw_dev_unload(struct adapter *padapter) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_dev_unload\n")); if (padapter->bup) { DBG_88E("===> rtw_dev_unload\n"); padapter->bDriverStopped = true; if (padapter->xmitpriv.ack_tx) rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); /* s3. */ if (padapter->intf_stop) padapter->intf_stop(padapter); /* s4. */ if (!padapter->pwrctrlpriv.bInternalAutoSuspend) rtw_stop_drv_threads(padapter); /* s5. */ if (!padapter->bSurpriseRemoved) { rtw_hal_deinit(padapter); padapter->bSurpriseRemoved = true; } padapter->bup = false; } else { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("r871x_dev_unload():padapter->bup == false\n")); } DBG_88E("<=== rtw_dev_unload\n"); RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n")); }
int proc_set_rssi_disp(struct file *file, const char __user *buffer, unsigned long count, void *data) { struct net_device *dev = (struct net_device *)data; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); char tmp[32]; u32 enable = 0; if (count < 1) { DBG_88E("argument size is less than 1\n"); return -EFAULT; } if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { int num = sscanf(tmp, "%x", &enable); if (num != 1) { DBG_88E("invalid set_rssi_disp parameter!\n"); return count; } if (enable) { DBG_88E("Turn On Rx RSSI Display Function\n"); padapter->bRxRSSIDisplay = enable; } else { DBG_88E("Turn Off Rx RSSI Display Function\n"); padapter->bRxRSSIDisplay = 0; } } return count; }
static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui) { DBG_88E("%s\n", __func__); if (!memcmp(WPS_OUI, oui, 4)) update_bcn_wps_ie(padapter); else DBG_88E("unknown OUI type!\n"); }
static void hal_notch_filter_8188e(struct adapter *adapter, bool enable) { if (enable) { DBG_88E("Enable notch filter\n"); usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) | BIT(1)); } else { DBG_88E("Disable notch filter\n"); usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) & ~BIT(1)); } }
void rtw_ips_pwr_down(struct adapter *padapter) { u32 start_time = jiffies; DBG_88E("===> rtw_ips_pwr_down...................\n"); padapter->net_closed = true; rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); }
void rtw_ips_pwr_down(struct adapter *padapter) { u32 start_time = rtw_get_current_time(); DBG_88E("===> rtw_ips_pwr_down...................\n"); padapter->bCardDisableWOHSM = true; padapter->net_closed = true; rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); padapter->bCardDisableWOHSM = false; DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); }
int rtw_ips_pwr_up(struct adapter *padapter) { int result; u32 start_time = jiffies; DBG_88E("===> rtw_ips_pwr_up..............\n"); rtw_reset_drv_sw(padapter); result = ips_netdrv_open(padapter); rtw_led_control(padapter, LED_CTL_NO_LINK); DBG_88E("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); return result; }
void rtw_ips_pwr_down(struct adapter *padapter) { unsigned long start_time = jiffies; DBG_88E("===> rtw_ips_pwr_down...................\n"); padapter->net_closed = true; rtw_led_control(padapter, LED_CTL_POWER_OFF); rtw_ips_dev_unload(padapter); DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", jiffies_to_msecs(jiffies - start_time)); }
int netdev_close(struct net_device *pnetdev) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); if (padapter->pwrctrlpriv.bInternalAutoSuspend) { if (padapter->pwrctrlpriv.rf_pwrstate == rf_off) padapter->pwrctrlpriv.ps_flag = true; } padapter->net_closed = true; if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) { DBG_88E("(2)88eu_drv - drv_close, bup =%d, hw_init_completed =%d\n", padapter->bup, padapter->hw_init_completed); /* s1. */ if (pnetdev) { if (!rtw_netif_queue_stopped(pnetdev)) rtw_netif_stop_queue(pnetdev); } /* s2. */ LeaveAllPowerSaveMode(padapter); rtw_disassoc_cmd(padapter, 500, false); /* s2-2. indicate disconnect to os */ rtw_indicate_disconnect(padapter); /* s2-3. */ rtw_free_assoc_resources(padapter, 1); /* s2-4. */ rtw_free_network_queue(padapter, true); /* Close LED */ rtw_led_control(padapter, LED_CTL_POWER_OFF); } nat25_db_cleanup(padapter); #ifdef CONFIG_88EU_P2P rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); #endif /* CONFIG_88EU_P2P */ kfree(dvobj->firmware.szFwBuffer); dvobj->firmware.szFwBuffer = NULL; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - drv_close\n")); DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); return 0; }
static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) { struct sta_priv *pstapriv = &padapter->stapriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; unsigned long irql; struct list_head *phead, *plist; struct sk_buff *newskb; struct sta_info *psta = NULL; s32 res; _enter_critical_bh(&pstapriv->asoc_list_lock, &irql); phead = &pstapriv->asoc_list; plist = get_next(phead); /* free sta asoc_queue */ while (!rtw_end_of_queue_search(phead, plist)) { psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); plist = get_next(plist); /* avoid come from STA1 and send back STA1 */ if (!memcmp(psta->hwaddr, &skb->data[6], 6)) continue; newskb = skb_copy(skb, GFP_ATOMIC); if (newskb) { memcpy(newskb->data, psta->hwaddr, 6); res = rtw_xmit(padapter, &newskb); if (res < 0) { DBG_88E("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__); pxmitpriv->tx_drop++; dev_kfree_skb_any(newskb); } else { pxmitpriv->tx_pkts++; } } else { DBG_88E("%s-%d: skb_copy() failed!\n", __func__, __LINE__); pxmitpriv->tx_drop++; _exit_critical_bh(&pstapriv->asoc_list_lock, &irql); return false; /* Caller shall tx this multicast frame via normal way. */ } } _exit_critical_bh(&pstapriv->asoc_list_lock, &irql); dev_kfree_skb_any(skb); return true; }
static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) { struct sta_priv *pstapriv = &padapter->stapriv; struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct list_head *phead, *plist; struct sk_buff *newskb; struct sta_info *psta = NULL; s32 res; spin_lock_bh(&pstapriv->asoc_list_lock); phead = &pstapriv->asoc_list; plist = phead->next; /* free sta asoc_queue */ while (phead != plist) { psta = container_of(plist, struct sta_info, asoc_list); plist = plist->next; /* avoid come from STA1 and send back STA1 */ if (!memcmp(psta->hwaddr, &skb->data[6], 6)) continue; newskb = skb_copy(skb, GFP_ATOMIC); if (newskb) { memcpy(newskb->data, psta->hwaddr, 6); res = rtw_xmit(padapter, &newskb); if (res < 0) { DBG_88E("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__); pxmitpriv->tx_drop++; dev_kfree_skb_any(newskb); } else { pxmitpriv->tx_pkts++; } } else { DBG_88E("%s-%d: skb_copy() failed!\n", __func__, __LINE__); pxmitpriv->tx_drop++; spin_unlock_bh(&pstapriv->asoc_list_lock); return false; /* Caller shall tx this multicast frame via normal way. */ } } spin_unlock_bh(&pstapriv->asoc_list_lock); dev_kfree_skb_any(skb); return true; }
inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) { if (!stainfo_offset_valid(offset)) DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset); return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); }
struct net_device *rtw_init_netdev(struct adapter *old_padapter) { struct adapter *padapter; struct net_device *pnetdev = NULL; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+init_net_dev\n")); if (old_padapter != NULL) pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter); if (!pnetdev) return NULL; pnetdev->dev.type = &wlan_type; padapter = rtw_netdev_priv(pnetdev); padapter->pnetdev = pnetdev; DBG_88E("register rtw_netdev_ops to netdev_ops\n"); pnetdev->netdev_ops = &rtw_netdev_ops; pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; /* step 2. */ loadparam(padapter, pnetdev); return pnetdev; }
static void rtw_usb_if1_deinit(struct adapter *if1) { struct net_device *pnetdev = if1->pnetdev; struct mlme_priv *pmlmepriv = &if1->mlmepriv; if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_disassoc_cmd(if1, 0, false); #ifdef CONFIG_88EU_AP_MODE free_mlme_ap_info(if1); #endif if (pnetdev) { /* will call netdev_close() */ unregister_netdev(pnetdev); rtw_proc_remove_one(pnetdev); } rtw_cancel_all_timer(if1); rtw_dev_unload(if1); DBG_88E("+r871xu_dev_remove, hw_init_completed=%d\n", if1->hw_init_completed); rtw_free_drv_sw(if1); if (pnetdev) rtw_free_netdev(pnetdev); }