1
/******************************************************************************
2
* Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4
* Based on the r8180 driver, which is:
5
* Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of version 2 of the GNU General Public License as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
* You should have received a copy of the GNU General Public License along with
16
* this program; if not, write to the Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19
* The full GNU General Public License is included in this distribution in the
20
* file called LICENSE.
22
* Contact Information:
23
* wlanfae <wlanfae@realtek.com>
24
******************************************************************************/
25
#ifdef _RTL8192_EXT_PATCH_
27
#include <asm/uaccess.h>
28
#include <linux/pci.h>
33
#include "rtl8192s/r8192S_phy.h"
34
#include "rtl8192s/r8192S_phyreg.h"
35
#include "rtl8192s/r8192S_rtl6052.h"
36
#include "rtl8192s/r8192S_Efuse.h"
37
#include "../../mshclass/msh_class.h"
39
int meshdev_up(struct net_device *meshdev,bool is_silent_reset)
41
struct meshdev_priv * mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
42
struct rtllib_device *ieee = mpriv->rtllib;
43
PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(mpriv->priv->rtllib->PowerSaveControl));
45
struct net_device *dev = ieee->dev;
46
RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
48
mpriv->rtllib->iw_mode = IW_MODE_MESH;
49
if(mpriv->priv->mesh_up){
50
RT_TRACE(COMP_INIT,"%s():mesh is up,return\n",__FUNCTION__);
54
mpriv->priv->ReceiveConfig =
55
RCR_APPFCS | RCR_APWRMGT | /*RCR_ADD3 |*/
56
RCR_AMF | RCR_ADF | RCR_APP_MIC | RCR_APP_ICV |
57
RCR_AICV | RCR_ACRC32 |
61
RCR_APP_PHYST_STAFF | RCR_APP_PHYST_RXFF |
62
(mpriv->priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) ;
65
mpriv->priv->ReceiveConfig = RCR_ADD3 |
68
RCR_AB | RCR_AM | RCR_APM |
69
RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
70
((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
74
if(!mpriv->priv->up) {
75
RT_TRACE(COMP_INIT, "Bringing up iface");
76
mpriv->priv->bfirst_init = true;
77
init_status = mpriv->priv->ops->initialize_adapter(dev);
78
if(init_status != true) {
79
RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
82
RT_TRACE(COMP_INIT, "start adapter finished\n");
83
RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
84
printk("==>%s():priv->up is 0\n",__FUNCTION__);
85
mpriv->rtllib->ieee_up=1;
86
mpriv->priv->bfirst_init = false;
87
#ifdef ENABLE_GPIO_RADIO_CTL
88
if(mpriv->priv->polling_timer_on == 0){
89
check_rfctrl_gpio_timer((unsigned long)dev);
92
mpriv->rtllib->current_network.channel = INIT_DEFAULT_CHAN;
93
mpriv->rtllib->current_mesh_network.channel = INIT_DEFAULT_CHAN;
94
if((mpriv->priv->mshobj->ext_patch_r819x_wx_set_mesh_chan) && (!is_silent_reset))
95
mpriv->priv->mshobj->ext_patch_r819x_wx_set_mesh_chan(dev,INIT_DEFAULT_CHAN);
96
if((mpriv->priv->mshobj->ext_patch_r819x_wx_set_channel) && (!is_silent_reset))
98
mpriv->priv->mshobj->ext_patch_r819x_wx_set_channel(mpriv->rtllib, INIT_DEFAULT_CHAN);
100
printk("%s():set chan %d\n",__FUNCTION__,INIT_DEFAULT_CHAN);
101
mpriv->rtllib->set_chan(dev, INIT_DEFAULT_CHAN);
102
dm_InitRateAdaptiveMask(dev);
103
watch_dog_timer_callback((unsigned long) dev);
106
rtllib_stop_scan(ieee);
109
if(!ieee->mesh_started) {
111
if(ieee->eRFPowerState!=eRfOn)
112
MgntActSet_RF_State(dev, eRfOn, ieee->RfOffReason);
114
if(mpriv->priv->mshobj && mpriv->priv->mshobj->ext_patch_rtl819x_up )
115
mpriv->priv->mshobj->ext_patch_rtl819x_up(mpriv->priv->mshobj);
118
if(!netif_queue_stopped(meshdev))
119
netif_start_queue(meshdev);
121
netif_wake_queue(meshdev);
123
rtllib_reset_queue(ieee);
126
mpriv->priv->mesh_up = 1;
128
RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
132
int meshdev_down(struct net_device *meshdev)
134
struct meshdev_priv * mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
135
struct rtllib_device *ieee = mpriv->rtllib;
136
struct r8192_priv *priv = (void*)ieee->priv;
137
struct net_device *dev = ieee->dev;
138
unsigned long flags = 0;
139
u8 RFInProgressTimeOut = 0;
140
if(priv->mesh_up == 0) {
141
RT_TRACE(COMP_ERR,"%s():ERR!!! mesh is already down\n",__FUNCTION__)
145
RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
147
if (netif_running(meshdev)) {
148
netif_stop_queue(meshdev);
153
printk("===>%s():priv->up is 0\n",__FUNCTION__);
154
priv->bDriverIsGoingToUnload = true;
156
rtl8192_irq_disable(dev);
157
rtl8192_cancel_deferred_work(priv);
159
cancel_delayed_work(&priv->rtllib->hw_wakeup_wq);
162
del_timer_sync(&priv->watch_dog_timer);
164
rtllib_softmac_stop_protocol(ieee, 1, true);
165
SPIN_LOCK_PRIV_RFPS(&priv->rf_ps_lock);
166
while(priv->RFChangeInProgress)
168
SPIN_UNLOCK_PRIV_RFPS(&priv->rf_ps_lock);
169
if(RFInProgressTimeOut > 100)
171
SPIN_LOCK_PRIV_RFPS(&priv->rf_ps_lock);
174
printk("===>%s():RF is in progress, need to wait until rf chang is done.\n",__FUNCTION__);
176
RFInProgressTimeOut ++;
177
SPIN_LOCK_PRIV_RFPS(&priv->rf_ps_lock);
179
printk("=====>%s(): priv->RFChangeInProgress = true\n",__FUNCTION__);
180
priv->RFChangeInProgress = true;
181
SPIN_UNLOCK_PRIV_RFPS(&priv->rf_ps_lock);
182
priv->ops->stop_adapter(dev, false);
183
SPIN_LOCK_PRIV_RFPS(&priv->rf_ps_lock);
184
printk("=====>%s(): priv->RFChangeInProgress = false\n",__FUNCTION__);
185
priv->RFChangeInProgress = false;
186
SPIN_UNLOCK_PRIV_RFPS(&priv->rf_ps_lock);
188
memset(&priv->rtllib->current_network, 0 , offsetof(struct rtllib_network, list));
189
priv->rtllib->current_network.channel = INIT_DEFAULT_CHAN;
190
#ifdef CONFIG_ASPM_OR_D3
193
memset(&ieee->current_mesh_network, 0 , offsetof(struct rtllib_network, list));
194
priv->rtllib->current_mesh_network.channel = INIT_DEFAULT_CHAN;
195
ieee->mesh_state = RTLLIB_NOLINK;
197
rtllib_softmac_stop_protocol(ieee, 1, true);
198
memset(&ieee->current_mesh_network, 0 , offsetof(struct rtllib_network, list));
199
if((ieee->current_network.channel > 0) && (ieee->current_network.channel < 15))
200
priv->rtllib->current_mesh_network.channel = ieee->current_network.channel;
202
priv->rtllib->current_mesh_network.channel = INIT_DEFAULT_CHAN;
203
printk("============>%s():priv->rtllib->current_mesh_network.channel is %d,ieee->current_network.channel is %d\n",__FUNCTION__,priv->rtllib->current_mesh_network.channel,ieee->current_network.channel);
205
ieee->mesh_state = RTLLIB_NOLINK;
206
ieee->iw_mode = IW_MODE_INFRA;
209
RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
214
static int meshdev_open(struct net_device *meshdev)
216
struct meshdev_priv * mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
217
struct rtllib_device *ieee = mpriv->rtllib;
218
struct r8192_priv *priv = (void*)ieee->priv;
221
SEM_DOWN_PRIV_WX(&priv->wx_sem);
222
ret = meshdev_up(meshdev,false);
223
SEM_UP_PRIV_WX(&priv->wx_sem);
228
static int meshdev_close(struct net_device *meshdev)
230
struct meshdev_priv * mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
231
struct rtllib_device *ieee = mpriv->rtllib;
232
struct r8192_priv *priv = (void *)ieee->priv;
235
SEM_DOWN_PRIV_WX(&priv->wx_sem);
236
ret = meshdev_down(meshdev);
237
SEM_UP_PRIV_WX(&priv->wx_sem);
242
extern int meshdev_wx_mesh(struct net_device *meshdev,
243
struct iw_request_info *info,
244
union iwreq_data *wrqu, char *extra);
245
static int meshdev_ioctl(struct net_device *meshdev, struct ifreq *rq, int cmd)
247
struct iwreq *wrq = (struct iwreq *)rq;
251
ret = meshdev_wx_mesh(meshdev, NULL, &(wrq->u), wrq->u.data.pointer);
256
struct net_device_stats *meshdev_stats(struct net_device *meshdev)
258
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
259
return &((struct meshdev_priv*)netdev_priv(meshdev))->stats;
261
return &((struct meshdev_priv*)meshdev->priv)->stats;
265
static int meshdev_tx(struct sk_buff *skb, struct net_device *meshdev)
267
struct meshdev_priv *mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
268
struct rtllib_device * ieee = mpriv->rtllib;
269
struct net_device *dev = ieee->dev;
271
memset(skb->cb,0,sizeof(skb->cb));
273
return rtllib_mesh_xmit(skb, dev);
276
static void meshdev_tx_timeout(struct net_device *meshdev)
278
struct meshdev_priv *mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
279
struct rtllib_device * ieee = mpriv->rtllib;
280
struct net_device *dev = ieee->dev;
285
#ifdef HAVE_NET_DEVICE_OPS
286
static const struct net_device_ops mesh_netdev_ops = {
287
.ndo_open = meshdev_open,
288
.ndo_stop = meshdev_close,
289
.ndo_get_stats = meshdev_stats,
290
.ndo_tx_timeout = meshdev_tx_timeout,
291
.ndo_do_ioctl = meshdev_ioctl,
292
.ndo_start_xmit = meshdev_tx,
296
void meshdev_init(struct net_device* meshdev)
298
struct meshdev_priv *mpriv;
299
ether_setup(meshdev);
301
#ifdef HAVE_NET_DEVICE_OPS
302
meshdev->netdev_ops = &mesh_netdev_ops;
304
meshdev->open = meshdev_open;
305
meshdev->stop = meshdev_close;
306
meshdev->tx_timeout = meshdev_tx_timeout;
307
meshdev->do_ioctl = meshdev_ioctl;
308
meshdev->get_stats = meshdev_stats;
309
meshdev->hard_start_xmit = meshdev_tx;
311
meshdev->wireless_handlers = &meshdev_wx_handlers_def;
312
meshdev->destructor = free_netdev;
313
meshdev->watchdog_timeo = HZ*3;
314
meshdev->type = ARPHRD_ETHER;
315
memset(meshdev->broadcast,0xFF, ETH_ALEN);
317
meshdev->watchdog_timeo = 3 * HZ;
319
mpriv = (struct meshdev_priv *)netdev_priv_rsl(meshdev);
320
memset(mpriv, 0, sizeof(struct meshdev_priv));
325
int meshdev_update_ext_chnl_offset_as_client(void *data)
327
struct rtllib_device *ieee = container_of_work_rsl(data, struct rtllib_device,
328
ext_update_extchnloffset_wq);
329
struct r8192_priv *priv = (void *)ieee->priv;
330
struct net_device *dev = ieee->dev;
331
struct mshclass *mshobj= priv->mshobj;
335
updateBW=mshobj->ext_patch_r819x_wx_update_beacon(dev,&bserverHT);
336
printk("$$$$$$ Cur_networ.chan=%d, cur_mesh_net.chan=%d,bserverHT=%d\n",
337
ieee->current_network.channel,ieee->current_mesh_network.channel,bserverHT);
339
if (bserverHT == 0) {
340
printk("===>server is not HT supported,set 20M\n");
341
HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
343
printk("===>updateBW is 1,bCurBW40MHz is %d,ieee->serverExtChlOffset is %d\n",
344
ieee->pHTInfo->bCurBW40MHz,ieee->serverExtChlOffset);
345
if (ieee->pHTInfo->bCurBW40MHz)
346
HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20_40, ieee->serverExtChlOffset);
348
HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, ieee->serverExtChlOffset);
351
printk("===>there is no same hostname server, ERR!!!\n");