diff options
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cfg.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/debugfs.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 127 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/rx.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/tx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 4 |
10 files changed, 125 insertions, 107 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 12a2ef9dacea..aa06070e5eab 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -32,6 +32,9 @@ u8 lbs_bg_rates[MAX_RATES] = 0x00, 0x00 }; +static int assoc_helper_wep_keys(struct lbs_private *priv, + struct assoc_request *assoc_req); + /** * @brief This function finds common rates between rates and card rates. * @@ -611,7 +614,7 @@ static int lbs_assoc_post(struct lbs_private *priv, if (status_code) { lbs_mac_event_disconnected(priv); - ret = -1; + ret = status_code; goto done; } @@ -814,7 +817,24 @@ static int lbs_try_associate(struct lbs_private *priv, goto out; ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); + /* If the association fails with current auth mode, let's + * try by changing the auth mode + */ + if ((priv->authtype_auto) && + (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) && + (assoc_req->secinfo.wep_enabled) && + (priv->connect_status != LBS_CONNECTED)) { + if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM) + priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; + else + priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; + if (!assoc_helper_wep_keys(priv, assoc_req)) + ret = lbs_associate(priv, assoc_req, + CMD_802_11_ASSOCIATE); + } + if (ret) + ret = -1; out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index ce7bec402a33..9d5d3ccf08c8 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -79,6 +79,7 @@ static const u32 cipher_suites[] = { static int lbs_cfg_set_channel(struct wiphy *wiphy, + struct net_device *netdev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index a48ccaffb288..de2caac11dd6 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -75,7 +75,7 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf, return -ENOMEM; pos += snprintf(buf+pos, len-pos, - "# | ch | rssi | bssid | cap | Qual | SSID \n"); + "# | ch | rssi | bssid | cap | Qual | SSID\n"); mutex_lock(&priv->lock); list_for_each_entry (iter_bss, &priv->network_list, list) { @@ -757,15 +757,12 @@ void lbs_debugfs_init(void) { if (!lbs_dir) lbs_dir = debugfs_create_dir("lbs_wireless", NULL); - - return; } void lbs_debugfs_remove(void) { if (lbs_dir) debugfs_remove(lbs_dir); - return; } void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6875e1498bd5..a54880e4ad2b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -134,6 +134,7 @@ struct lbs_private { u8 wpa_ie_len; u16 wep_tx_keyidx; struct enc_key wep_keys[4]; + u8 authtype_auto; /* Wake On LAN */ uint32_t wol_criteria; diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 7d1a3c6b6ce0..64dd345d30f5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -35,6 +35,8 @@ #include <linux/mmc/card.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio.h> +#include <linux/mmc/host.h> #include "host.h" #include "decl.h" @@ -313,12 +315,30 @@ out: return ret; } +static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) +{ + u8 status; + unsigned long timeout; + int ret = 0; + + timeout = jiffies + HZ; + while (1) { + status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); + if (ret) + return ret; + if ((status & condition) == condition) + break; + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + mdelay(1); + } + return ret; +} + static int if_sdio_card_to_host(struct if_sdio_card *card) { int ret; - u8 status; u16 size, type, chunk; - unsigned long timeout; lbs_deb_enter(LBS_DEB_SDIO); @@ -333,19 +353,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) goto out; } - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto out; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto out; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); + if (ret) + goto out; /* * The transfer must be in one transaction or the firmware @@ -412,8 +422,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) { struct if_sdio_card *card; struct if_sdio_packet *packet; - unsigned long timeout; - u8 status; int ret; unsigned long flags; @@ -433,25 +441,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) sdio_claim_host(card->func); - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); + ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY); + if (ret == 0) { + ret = sdio_writesb(card->func, card->ioport, + packet->buffer, packet->nb); } - ret = sdio_writesb(card->func, card->ioport, - packet->buffer, packet->nb); if (ret) - goto release; -release: + lbs_pr_err("error %d sending packet to firmware\n", ret); + sdio_release_host(card->func); kfree(packet); @@ -464,10 +462,11 @@ release: /* Firmware */ /********************************************************************/ +#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) + static int if_sdio_prog_helper(struct if_sdio_card *card) { int ret; - u8 status; const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; @@ -499,20 +498,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; + + /* On some platforms (like Davinci) the chip needs more time + * between helper blocks. + */ + mdelay(2); chunk_size = min(size, (size_t)60); @@ -582,7 +575,6 @@ out: static int if_sdio_prog_real(struct if_sdio_card *card) { int ret; - u8 status; const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; @@ -614,20 +606,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card) size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); if (ret) @@ -943,6 +924,7 @@ static int if_sdio_probe(struct sdio_func *func, int ret, i; unsigned int model; struct if_sdio_packet *packet; + struct mmc_host *host = func->card->host; lbs_deb_enter(LBS_DEB_SDIO); @@ -1023,6 +1005,25 @@ static int if_sdio_probe(struct sdio_func *func, if (ret) goto disable; + /* For 1-bit transfers to the 8686 model, we need to enable the + * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 + * bit to allow access to non-vendor registers. */ + if ((card->model == IF_SDIO_MODEL_8686) && + (host->caps & MMC_CAP_SDIO_IRQ) && + (host->ios.bus_width == MMC_BUS_WIDTH_1)) { + u8 reg; + + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret); + if (ret) + goto release_int; + + reg |= SDIO_BUS_ECSI; + sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret); + if (ret) + goto release_int; + } + card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); if (ret) goto release_int; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index fcea5741ba62..f41594c7ac16 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -133,8 +133,6 @@ static void if_usb_write_bulk_callback(struct urb *urb) /* print the failure status number for debug */ lbs_pr_info("URB in failure status: %d\n", urb->status); } - - return; } /** @@ -651,8 +649,6 @@ static void if_usb_receive_fwload(struct urb *urb) if_usb_submit_rx_urb_fwload(cardp); kfree(syncfwheader); - - return; } #define MRVDRV_MIN_PKT_LEN 30 diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 598080414b17..d9b8ee130c45 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -229,7 +229,7 @@ static void lbs_tx_timeout(struct net_device *dev) lbs_pr_err("tx watch dog timeout\n"); - dev->trans_start = jiffies; + dev->trans_start = jiffies; /* prevent tx timeout */ if (priv->currenttxskb) lbs_send_tx_feedback(priv, 0); @@ -319,7 +319,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, struct net_device *dev, int nr_addrs) { int i = nr_addrs; - struct dev_mc_list *mc_list; + struct netdev_hw_addr *ha; int cnt; if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST)) @@ -327,19 +327,19 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, netif_addr_lock_bh(dev); cnt = netdev_mc_count(dev); - netdev_for_each_mc_addr(mc_list, dev) { - if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { + netdev_for_each_mc_addr(ha, dev) { + if (mac_in_list(cmd->maclist, nr_addrs, ha->addr)) { lbs_deb_net("mcast address %s:%pM skipped\n", dev->name, - mc_list->dmi_addr); + ha->addr); cnt--; continue; } if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE) break; - memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN); + memcpy(&cmd->maclist[6*i], ha->addr, ETH_ALEN); lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name, - mc_list->dmi_addr); + ha->addr); i++; cnt--; } @@ -836,6 +836,7 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->is_auto_deep_sleep_enabled = 0; priv->wakeup_dev_required = 0; init_waitqueue_head(&priv->ds_awake_q); + priv->authtype_auto = 1; mutex_init(&priv->lock); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 784dae714705..a115bfa9513a 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -39,10 +39,10 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, struct sk_buff *skb); /** - * @brief This function computes the avgSNR . + * @brief This function computes the avgSNR . * - * @param priv A pointer to struct lbs_private structure - * @return avgSNR + * @param priv A pointer to struct lbs_private structure + * @return avgSNR */ static u8 lbs_getavgsnr(struct lbs_private *priv) { @@ -57,10 +57,10 @@ static u8 lbs_getavgsnr(struct lbs_private *priv) } /** - * @brief This function computes the AvgNF + * @brief This function computes the AvgNF * - * @param priv A pointer to struct lbs_private structure - * @return AvgNF + * @param priv A pointer to struct lbs_private structure + * @return AvgNF */ static u8 lbs_getavgnf(struct lbs_private *priv) { @@ -75,11 +75,11 @@ static u8 lbs_getavgnf(struct lbs_private *priv) } /** - * @brief This function save the raw SNR/NF to our internel buffer + * @brief This function save the raw SNR/NF to our internel buffer * - * @param priv A pointer to struct lbs_private structure - * @param prxpd A pointer to rxpd structure of received packet - * @return n/a + * @param priv A pointer to struct lbs_private structure + * @param prxpd A pointer to rxpd structure of received packet + * @return n/a */ static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) { @@ -90,15 +90,14 @@ static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) priv->nextSNRNF++; if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR) priv->nextSNRNF = 0; - return; } /** - * @brief This function computes the RSSI in received packet. + * @brief This function computes the RSSI in received packet. * - * @param priv A pointer to struct lbs_private structure - * @param prxpd A pointer to rxpd structure of received packet - * @return n/a + * @param priv A pointer to struct lbs_private structure + * @param prxpd A pointer to rxpd structure of received packet + * @return n/a */ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) { @@ -135,9 +134,9 @@ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) * @brief This function processes received packet and forwards it * to kernel/upper layer * - * @param priv A pointer to struct lbs_private - * @param skb A pointer to skb which includes the received packet - * @return 0 or -1 + * @param priv A pointer to struct lbs_private + * @param skb A pointer to skb which includes the received packet + * @return 0 or -1 */ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) { @@ -197,7 +196,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) * before the snap_type. */ p_ethhdr = (struct ethhdr *) - ((u8 *) & p_rx_pkt->eth803_hdr + ((u8 *) &p_rx_pkt->eth803_hdr + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) - sizeof(p_rx_pkt->eth803_hdr.dest_addr) - sizeof(p_rx_pkt->eth803_hdr.src_addr) @@ -214,7 +213,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; } else { lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", - (u8 *) & p_rx_pkt->rfc1042_hdr, + (u8 *) &p_rx_pkt->rfc1042_hdr, sizeof(p_rx_pkt->rfc1042_hdr)); /* Chop off the rxpd */ @@ -255,8 +254,8 @@ EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); * @brief This function converts Tx/Rx rates from the Marvell WLAN format * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) * - * @param rate Input rate - * @return Output Rate (0 if invalid) + * @param rate Input rate + * @return Output Rate (0 if invalid) */ static u8 convert_mv_rate_to_radiotap(u8 rate) { @@ -295,9 +294,9 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) * @brief This function processes a received 802.11 packet and forwards it * to kernel/upper layer * - * @param priv A pointer to struct lbs_private - * @param skb A pointer to skb which includes the received packet - * @return 0 or -1 + * @param priv A pointer to struct lbs_private + * @param skb A pointer to skb which includes the received packet + * @return 0 or -1 */ static int process_rxed_802_11_packet(struct lbs_private *priv, struct sk_buff *skb) @@ -314,7 +313,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, p_rx_pkt = (struct rx80211packethdr *) skb->data; prxpd = &p_rx_pkt->rx_pd; - // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); + /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */ if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { lbs_deb_rx("rx err: frame received with bad length\n"); diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index 52d244ea3d97..a9bf658659eb 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -147,8 +147,6 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - dev->trans_start = jiffies; - if (priv->monitormode) { /* Keep the skb to echo it back once Tx feedback is received from FW */ diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 9b555884b08a..f96a96031a50 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -1441,8 +1441,10 @@ static int lbs_set_encode(struct net_device *dev, set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); if (dwrq->flags & IW_ENCODE_RESTRICTED) { + priv->authtype_auto = 0; assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { + priv->authtype_auto = 0; assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } @@ -1621,8 +1623,10 @@ static int lbs_set_encodeext(struct net_device *dev, goto out; if (dwrq->flags & IW_ENCODE_RESTRICTED) { + priv->authtype_auto = 0; assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { + priv->authtype_auto = 0; assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } |