static int netdev_close(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev); /* Close LED*/ padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF); msleep(200); /*s1.*/ if (pnetdev) { if (!netif_queue_stopped(pnetdev)) netif_stop_queue(pnetdev); } /*s2.*/ /*s2-1. issue disassoc_cmd to fw*/ r8712_disassoc_cmd(padapter); /*s2-2. indicate disconnect to os*/ r8712_ind_disconnect(padapter); /*s2-3.*/ r8712_free_assoc_resources(padapter); /*s2-4.*/ r8712_free_network_queue(padapter); /*Stop driver mlme relation timer*/ stop_drv_timers(padapter); return 0; }
struct net_device *r8712_init_netdev(void) { struct _adapter *padapter; struct net_device *pnetdev; pnetdev = alloc_etherdev(sizeof(struct _adapter)); if (!pnetdev) return NULL; if (dev_alloc_name(pnetdev, ifname) < 0) { strcpy(ifname, "wlan%d"); dev_alloc_name(pnetdev, ifname); } padapter = (struct _adapter *) _netdev_priv(pnetdev); padapter->pnetdev = pnetdev; printk(KERN_INFO "r8712u: register rtl8712_netdev_ops to" " netdev_ops\n"); pnetdev->netdev_ops = &rtl8712_netdev_ops; pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ pnetdev->wireless_handlers = (struct iw_handler_def *) &r871x_handlers_def; /*step 2.*/ loadparam(padapter, pnetdev); netif_carrier_off(pnetdev); padapter->pid = 0; /* Initial the PID value used for HW PBC.*/ return pnetdev; }
static int netdev_open(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev); if (padapter->bup == false) { padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; padapter->bup = true; if (rtl871x_hal_init(padapter) != _SUCCESS) goto netdev_open_error; if (r8712_initmac == NULL) /* Use the mac address stored in the Efuse */ memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); else { /* We have to inform f/w to use user-supplied MAC * address. */ msleep(200); r8712_setMacAddr_cmd(padapter, (u8 *)pnetdev->dev_addr); /* * The "myid" function will get the wifi mac address * from eeprompriv structure instead of netdev * structure. So, we have to overwrite the mac_addr * stored in the eeprompriv structure. In this case, * the real mac address won't be used anymore. So that, * the eeprompriv.mac_addr should store the mac which * users specify. */ memcpy(padapter->eeprompriv.mac_addr, pnetdev->dev_addr, ETH_ALEN); } if (start_drv_threads(padapter) != _SUCCESS) goto netdev_open_error; if (padapter->dvobjpriv.inirp_init == NULL) goto netdev_open_error; else padapter->dvobjpriv.inirp_init(padapter); r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, padapter->registrypriv.smart_ps); } if (!netif_queue_stopped(pnetdev)) netif_start_queue(pnetdev); else netif_wake_queue(pnetdev); if (video_mode) enable_video_mode(padapter, cbw40_enable); /* start driver mlme relation timer */ start_drv_timers(padapter); padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); return 0; netdev_open_error: padapter->bup = false; netif_carrier_off(pnetdev); netif_stop_queue(pnetdev); return -1; }
static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p) { struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev); struct sockaddr *addr = p; if (padapter->bup == false) memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN); return 0; }
static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev); struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct recv_priv *precvpriv = &(padapter->recvpriv); padapter->stats.tx_packets = pxmitpriv->tx_pkts; padapter->stats.rx_packets = precvpriv->rx_pkts; padapter->stats.tx_dropped = pxmitpriv->tx_drop; padapter->stats.rx_dropped = precvpriv->rx_drop; padapter->stats.tx_bytes = pxmitpriv->tx_bytes; padapter->stats.rx_bytes = precvpriv->rx_bytes; return &padapter->stats; }
/* * drv_init() - a device potentially for us * * notes: drv_init() is called when the bus driver has located a card for us * to support. We accept the new device by returning 0. */ static int r871xu_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid) { uint status; struct _adapter *padapter = NULL; struct dvobj_priv *pdvobjpriv; struct net_device *pnetdev; printk(KERN_INFO "r8712u: DriverVersion: %s\n", DRVER); /* In this probe function, O.S. will provide the usb interface pointer * to driver. We have to increase the reference count of the usb device * structure by using the usb_get_dev function. */ usb_get_dev(interface_to_usbdev(pusb_intf)); pintf = pusb_intf; /* step 1. */ pnetdev = r8712_init_netdev(); if (!pnetdev) goto error; padapter = (struct _adapter *)_netdev_priv(pnetdev); disable_ht_for_spec_devid(pdid, padapter); pdvobjpriv = &padapter->dvobjpriv; pdvobjpriv->padapter = padapter; padapter->dvobjpriv.pusbdev = interface_to_usbdev(pusb_intf); usb_set_intfdata(pusb_intf, pnetdev); SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); /* step 2. */ padapter->dvobj_init = &r8712_usb_dvobj_init; padapter->dvobj_deinit = &r8712_usb_dvobj_deinit; padapter->halpriv.hal_bus_init = &r8712_usb_hal_bus_init; padapter->dvobjpriv.inirp_init = &r8712_usb_inirp_init; padapter->dvobjpriv.inirp_deinit = &r8712_usb_inirp_deinit; /* step 3. * initialize the dvobj_priv */ if (padapter->dvobj_init == NULL) goto error; else { status = padapter->dvobj_init(padapter); if (status != _SUCCESS) goto error; } /* step 4. */ status = r8712_init_drv_sw(padapter); if (status == _FAIL) goto error; /* step 5. read efuse/eeprom data and get mac_addr */ { int i, offset; u8 mac[6]; u8 tmpU1b, AutoloadFail, eeprom_CustomerID; u8 *pdata = padapter->eeprompriv.efuse_eeprom_data; tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/ /* To check system boot selection.*/ printk(KERN_INFO "r8712u: Boot from %s: Autoload %s\n", (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE", (tmpU1b & _EEPROM_EN) ? "OK" : "Failed"); /* To check autoload success or not.*/ if (tmpU1b & _EEPROM_EN) { AutoloadFail = true; /* The following operations prevent Efuse leakage by * turning on 2.5V. */ tmpU1b = r8712_read8(padapter, EFUSE_TEST+3); r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80); msleep(20); r8712_write8(padapter, EFUSE_TEST + 3, (tmpU1b & (~BIT(7)))); /* Retrieve Chip version. * Recognize IC version by Reg0x4 BIT15. */ tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) & 0x1F); if (tmpU1b == 0x3) padapter->registrypriv.chip_version = RTL8712_3rdCUT; else padapter->registrypriv.chip_version = (tmpU1b >> 1) + 1; switch (padapter->registrypriv.chip_version) { case RTL8712_1stCUT: case RTL8712_2ndCUT: case RTL8712_3rdCUT: break; default: padapter->registrypriv.chip_version = RTL8712_2ndCUT; break; } for (i = 0, offset = 0; i < 128; i += 8, offset++) r8712_efuse_pg_packet_read(padapter, offset, &pdata[i]); if (r8712_initmac) { /* Users specify the mac address */ int jj, kk; for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) mac[jj] = key_2char2num(r8712_initmac[kk], r8712_initmac[kk + 1]); } else { /* Use the mac address stored in the Efuse * offset = 0x12 for usb in efuse */ memcpy(mac, &pdata[0x12], ETH_ALEN); } eeprom_CustomerID = pdata[0x52]; switch (eeprom_CustomerID) { case EEPROM_CID_ALPHA: padapter->eeprompriv.CustomerID = RT_CID_819x_ALPHA; break; case EEPROM_CID_CAMEO: padapter->eeprompriv.CustomerID = RT_CID_819x_CAMEO; break; case EEPROM_CID_SITECOM: padapter->eeprompriv.CustomerID = RT_CID_819x_Sitecom; break; case EEPROM_CID_COREGA: padapter->eeprompriv.CustomerID = RT_CID_COREGA; break; case EEPROM_CID_Senao: padapter->eeprompriv.CustomerID = RT_CID_819x_Senao; break; case EEPROM_CID_EDIMAX_BELKIN: padapter->eeprompriv.CustomerID = RT_CID_819x_Edimax_Belkin; break; case EEPROM_CID_SERCOMM_BELKIN: padapter->eeprompriv.CustomerID = RT_CID_819x_Sercomm_Belkin; break; case EEPROM_CID_WNC_COREGA: padapter->eeprompriv.CustomerID = RT_CID_819x_WNC_COREGA; break; case EEPROM_CID_WHQL: break; case EEPROM_CID_NetCore: padapter->eeprompriv.CustomerID = RT_CID_819x_Netcore; break; case EEPROM_CID_CAMEO1: padapter->eeprompriv.CustomerID = RT_CID_819x_CAMEO1; break; case EEPROM_CID_CLEVO: padapter->eeprompriv.CustomerID = RT_CID_819x_CLEVO; break; default: padapter->eeprompriv.CustomerID = RT_CID_DEFAULT; break; } printk(KERN_INFO "r8712u: CustomerID = 0x%.4x\n", padapter->eeprompriv.CustomerID); /* Led mode */ switch (padapter->eeprompriv.CustomerID) { case RT_CID_DEFAULT: case RT_CID_819x_ALPHA: case RT_CID_819x_CAMEO: padapter->ledpriv.LedStrategy = SW_LED_MODE1; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Sitecom: padapter->ledpriv.LedStrategy = SW_LED_MODE2; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_COREGA: case RT_CID_819x_Senao: padapter->ledpriv.LedStrategy = SW_LED_MODE3; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Edimax_Belkin: padapter->ledpriv.LedStrategy = SW_LED_MODE4; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_Sercomm_Belkin: padapter->ledpriv.LedStrategy = SW_LED_MODE5; padapter->ledpriv.bRegUseLed = true; break; case RT_CID_819x_WNC_COREGA: padapter->ledpriv.LedStrategy = SW_LED_MODE6; padapter->ledpriv.bRegUseLed = true; break; default: padapter->ledpriv.LedStrategy = SW_LED_MODE0; padapter->ledpriv.bRegUseLed = false; break; } } else