aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rtl8192u/r8192U_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rtl8192u/r8192U_core.c')
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c198
1 files changed, 131 insertions, 67 deletions
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 8c1d73719147..dd0970facdf5 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -253,7 +253,7 @@ u32 read_cam(struct net_device *dev, u8 addr)
return data;
}
-void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
+int write_nic_byte_E(struct net_device *dev, int indx, u8 data)
{
int status;
struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -261,7 +261,7 @@ void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
u8 *usbdata = kzalloc(sizeof(data), GFP_KERNEL);
if (!usbdata)
- return;
+ return -ENOMEM;
*usbdata = data;
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
@@ -269,9 +269,12 @@ void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
indx | 0xfe00, 0, usbdata, 1, HZ / 2);
kfree(usbdata);
- if (status < 0)
+ if (status < 0){
netdev_err(dev, "write_nic_byte_E TimeOut! status: %d\n",
status);
+ return status;
+ }
+ return 0;
}
int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
@@ -299,7 +302,7 @@ int read_nic_byte_E(struct net_device *dev, int indx, u8 *data)
}
/* as 92U has extend page from 4 to 16, so modify functions below. */
-void write_nic_byte(struct net_device *dev, int indx, u8 data)
+int write_nic_byte(struct net_device *dev, int indx, u8 data)
{
int status;
@@ -308,7 +311,7 @@ void write_nic_byte(struct net_device *dev, int indx, u8 data)
u8 *usbdata = kzalloc(sizeof(data), GFP_KERNEL);
if (!usbdata)
- return;
+ return -ENOMEM;
*usbdata = data;
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
@@ -317,12 +320,16 @@ void write_nic_byte(struct net_device *dev, int indx, u8 data)
usbdata, 1, HZ / 2);
kfree(usbdata);
- if (status < 0)
+ if (status < 0) {
netdev_err(dev, "write_nic_byte TimeOut! status: %d\n", status);
+ return status;
+ }
+
+ return 0;
}
-void write_nic_word(struct net_device *dev, int indx, u16 data)
+int write_nic_word(struct net_device *dev, int indx, u16 data)
{
int status;
@@ -331,7 +338,7 @@ void write_nic_word(struct net_device *dev, int indx, u16 data)
u16 *usbdata = kzalloc(sizeof(data), GFP_KERNEL);
if (!usbdata)
- return;
+ return -ENOMEM;
*usbdata = data;
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
@@ -340,12 +347,16 @@ void write_nic_word(struct net_device *dev, int indx, u16 data)
usbdata, 2, HZ / 2);
kfree(usbdata);
- if (status < 0)
+ if (status < 0) {
netdev_err(dev, "write_nic_word TimeOut! status: %d\n", status);
+ return status;
+ }
+
+ return 0;
}
-void write_nic_dword(struct net_device *dev, int indx, u32 data)
+int write_nic_dword(struct net_device *dev, int indx, u32 data)
{
int status;
@@ -354,7 +365,7 @@ void write_nic_dword(struct net_device *dev, int indx, u32 data)
u32 *usbdata = kzalloc(sizeof(data), GFP_KERNEL);
if (!usbdata)
- return;
+ return -ENOMEM;
*usbdata = data;
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
@@ -364,9 +375,13 @@ void write_nic_dword(struct net_device *dev, int indx, u32 data)
kfree(usbdata);
- if (status < 0)
+ if (status < 0) {
netdev_err(dev, "write_nic_dword TimeOut! status: %d\n",
status);
+ return status;
+ }
+
+ return 0;
}
@@ -2361,8 +2376,7 @@ static void rtl8192_init_priv_lock(struct r8192_priv *priv)
{
spin_lock_init(&priv->tx_lock);
spin_lock_init(&priv->irq_lock);
- sema_init(&priv->wx_sem, 1);
- sema_init(&priv->rf_sem, 1);
+ mutex_init(&priv->wx_mutex);
mutex_init(&priv->mutex);
}
@@ -2421,7 +2435,7 @@ static inline u16 endian_swap(u16 *data)
return *data;
}
-static void rtl8192_read_eeprom_info(struct net_device *dev)
+static int rtl8192_read_eeprom_info(struct net_device *dev)
{
u16 wEPROM_ID = 0;
u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
@@ -2429,9 +2443,13 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
u16 tmpValue = 0;
int i;
+ int ret;
RT_TRACE(COMP_EPROM, "===========>%s()\n", __func__);
- wEPROM_ID = eprom_read(dev, 0); /* first read EEPROM ID out; */
+ ret = eprom_read(dev, 0); /* first read EEPROM ID out; */
+ if (ret < 0)
+ return ret;
+ wEPROM_ID = (u16)ret;
RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
if (wEPROM_ID != RTL8190_EEPROM_ID)
@@ -2443,13 +2461,25 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
if (bLoad_From_EEPOM) {
tmpValue = eprom_read(dev, EEPROM_VID >> 1);
+ ret = eprom_read(dev, EEPROM_VID >> 1);
+ if (ret < 0)
+ return ret;
+ tmpValue = (u16)ret;
priv->eeprom_vid = endian_swap(&tmpValue);
- priv->eeprom_pid = eprom_read(dev, EEPROM_PID >> 1);
- tmpValue = eprom_read(dev, EEPROM_ChannelPlan >> 1);
+ ret = eprom_read(dev, EEPROM_PID >> 1);
+ if (ret < 0)
+ return ret;
+ priv->eeprom_pid = (u16)ret;
+ ret = eprom_read(dev, EEPROM_ChannelPlan >> 1);
+ if (ret < 0)
+ return ret;
+ tmpValue = (u16)ret;
priv->eeprom_ChannelPlan = (tmpValue & 0xff00) >> 8;
priv->btxpowerdata_readfromEEPORM = true;
- priv->eeprom_CustomerID =
- eprom_read(dev, (EEPROM_Customer_ID >> 1)) >> 8;
+ ret = eprom_read(dev, (EEPROM_Customer_ID >> 1)) >> 8;
+ if (ret < 0)
+ return ret;
+ priv->eeprom_CustomerID = (u16)ret;
} else {
priv->eeprom_vid = 0;
priv->eeprom_pid = 0;
@@ -2467,10 +2497,10 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
int i;
for (i = 0; i < 6; i += 2) {
- u16 tmp = 0;
-
- tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1));
- *(u16 *)(&dev->dev_addr[i]) = tmp;
+ ret = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1));
+ if (ret < 0)
+ return ret;
+ *(u16 *)(&dev->dev_addr[i]) = (u16)ret;
}
} else {
memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
@@ -2482,52 +2512,72 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
if (priv->card_8192_version == (u8)VERSION_819xU_A) {
/* read Tx power gain offset of legacy OFDM to HT rate */
- if (bLoad_From_EEPOM)
- priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff >> 1)) & 0xff00) >> 8;
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_TxPowerDiff >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROMTxPowerDiff = ((u16)ret & 0xff00) >> 8;
+ } else
priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
/* read ThermalMeter from EEPROM */
- if (bLoad_From_EEPOM)
- priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter >> 1)) & 0x00ff);
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_ThermalMeter >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROMThermalMeter = (u8)((u16)ret & 0x00ff);
+ } else
priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
/* for tx power track */
priv->TSSI_13dBm = priv->EEPROMThermalMeter * 100;
/* read antenna tx power offset of B/C/D to A from EEPROM */
- if (bLoad_From_EEPOM)
- priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff >> 1)) & 0x0f00) >> 8;
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_PwDiff >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROMPwDiff = ((u16)ret & 0x0f00) >> 8;
+ } else
priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
/* Read CrystalCap from EEPROM */
- if (bLoad_From_EEPOM)
- priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap >> 1)) & 0x0f);
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_CrystalCap >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROMCrystalCap = (u16)ret & 0x0f;
+ } else
priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
/* get per-channel Tx power level */
- if (bLoad_From_EEPOM)
- priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver >> 1)) & 0xff00) >> 8;
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_TxPwIndex_Ver >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROM_Def_Ver = ((u16)ret & 0xff00) >> 8;
+ } else
priv->EEPROM_Def_Ver = 1;
RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */
int i;
- if (bLoad_From_EEPOM)
- priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK >> 1)) & 0xff) >> 8;
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_TxPwIndex_CCK >> 1));
+ if (ret < 0)
+ return ret;
+ priv->EEPROMTxPowerLevelCCK = ((u16)ret & 0xff) >> 8;
+ } else
priv->EEPROMTxPowerLevelCCK = 0x10;
RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
for (i = 0; i < 3; i++) {
if (bLoad_From_EEPOM) {
- tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G + i) >> 1);
+ ret = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G + i) >> 1);
+ if ( ret < 0)
+ return ret;
if (((EEPROM_TxPwIndex_OFDM_24G + i) % 2) == 0)
- tmpValue = tmpValue & 0x00ff;
+ tmpValue = (u16)ret & 0x00ff;
else
- tmpValue = (tmpValue & 0xff00) >> 8;
+ tmpValue = ((u16)ret & 0xff00) >> 8;
} else {
tmpValue = 0x10;
}
@@ -2536,17 +2586,21 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
}
} else if (priv->EEPROM_Def_Ver == 1) {
if (bLoad_From_EEPOM) {
- tmpValue = eprom_read(dev,
- EEPROM_TxPwIndex_CCK_V1 >> 1);
- tmpValue = (tmpValue & 0xff00) >> 8;
+ ret = eprom_read(dev, EEPROM_TxPwIndex_CCK_V1 >> 1);
+ if (ret < 0)
+ return ret;
+ tmpValue = ((u16)ret & 0xff00) >> 8;
} else {
tmpValue = 0x10;
}
priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
- if (bLoad_From_EEPOM)
- tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2) >> 1);
- else
+ if (bLoad_From_EEPOM) {
+ ret = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2) >> 1);
+ if (ret < 0)
+ return ret;
+ tmpValue = (u16)ret;
+ } else
tmpValue = 0x1010;
*((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
if (bLoad_From_EEPOM)
@@ -2644,6 +2698,8 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
init_rate_adaptive(dev);
RT_TRACE(COMP_EPROM, "<===========%s()\n", __func__);
+
+ return 0;
}
static short rtl8192_get_channel_map(struct net_device *dev)
@@ -2664,6 +2720,7 @@ static short rtl8192_get_channel_map(struct net_device *dev)
static short rtl8192_init(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+ int err;
memset(&(priv->stats), 0, sizeof(struct Stats));
memset(priv->txqueue_to_outpipemap, 0, 9);
@@ -2685,7 +2742,14 @@ static short rtl8192_init(struct net_device *dev)
rtl8192_init_priv_lock(priv);
rtl8192_init_priv_task(dev);
rtl8192_get_eeprom_size(dev);
- rtl8192_read_eeprom_info(dev);
+ err = rtl8192_read_eeprom_info(dev);
+ if (err) {
+ DMESG("Reading EEPROM info failed");
+ kfree(priv->pFirmware);
+ priv->pFirmware = NULL;
+ free_ieee80211(dev);
+ return err;
+ }
rtl8192_get_channel_map(dev);
init_hal_dm(dev);
setup_timer(&priv->watch_dog_timer, watch_dog_timer_callback,
@@ -3303,12 +3367,12 @@ RESET_START:
/* Set the variable for reset. */
priv->ResetProgress = RESET_TYPE_SILENT;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (priv->up == 0) {
RT_TRACE(COMP_ERR,
"%s():the driver is not up! return\n",
__func__);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return;
}
priv->up = 0;
@@ -3323,19 +3387,19 @@ RESET_START:
ieee->sync_scan_hurryup = 1;
if (ieee->state == IEEE80211_LINKED) {
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
netdev_dbg(dev, "ieee->state is IEEE80211_LINKED\n");
ieee80211_stop_send_beacons(priv->ieee80211);
del_timer_sync(&ieee->associate_timer);
cancel_delayed_work(&ieee->associate_retry_wq);
ieee80211_stop_scan(ieee);
netif_carrier_off(dev);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
} else {
netdev_dbg(dev, "ieee->state is NOT LINKED\n");
ieee80211_softmac_stop_protocol(priv->ieee80211);
}
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
RT_TRACE(COMP_RESET,
"%s():<==========down process is finished\n",
__func__);
@@ -3533,9 +3597,9 @@ static int rtl8192_open(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtl8192_up(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -3556,11 +3620,11 @@ static int rtl8192_close(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtl8192_down(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -3632,11 +3696,11 @@ static void rtl8192_restart(struct work_struct *work)
reset_wq);
struct net_device *dev = priv->ieee80211->dev;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
rtl8192_commit(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
}
static void r8192_set_multicast(struct net_device *dev)
@@ -3659,12 +3723,12 @@ static int r8192_set_mac_adr(struct net_device *dev, void *mac)
struct r8192_priv *priv = ieee80211_priv(dev);
struct sockaddr *addr = mac;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ether_addr_copy(dev->dev_addr, addr->sa_data);
schedule_work(&priv->reset_wq);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -3681,7 +3745,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct iw_point *p = &wrq->u.data;
struct ieee_param *ipw = NULL;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (p->length < sizeof(struct ieee_param) || !p->pointer) {
@@ -3774,7 +3838,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
kfree(ipw);
ipw = NULL;
out:
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}