rtl8188eu: Copy the code from the kernel into a new branch

This version takes advantage of all the cleanups to the code. It has
been modified to build on older kernels.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
This commit is contained in:
Larry Finger 2022-06-08 18:46:35 -05:00
parent 30901e601a
commit 77d786b6e8
156 changed files with 6564 additions and 41050 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,47 +1,27 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. i*/
#define _RTW_BR_EXT_C_
#include <linux/version.h>
#include <linux/if_arp.h>
#include <net/ip.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
#include <net/ipx.h>
#endif
#include <linux/atalk.h>
#include <linux/udp.h>
#include <linux/if_pppox.h>
#include "../include/linux/if_arp.h"
#include "../include/net/ip.h"
#include "../include/linux/atalk.h"
#include "../include/linux/udp.h"
#include "../include/linux/if_pppox.h"
#include <drv_types.h>
#include "rtw_br_ext.h"
#include <usb_osintf.h>
#include <recv_osdep.h>
#include "../include/drv_types.h"
#include "../include/rtw_br_ext.h"
#include "../include/usb_osintf.h"
#include "../include/recv_osdep.h"
#ifndef csum_ipv6_magic
#include <net/ip6_checksum.h>
#include "../include/net/ip6_checksum.h"
#endif
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <net/ndisc.h>
#include <net/checksum.h>
#include "../include/linux/ipv6.h"
#include "../include/linux/icmpv6.h"
#include "../include/net/ndisc.h"
#include "../include/net/checksum.h"
#define NAT25_IPV4 01
#define NAT25_IPV6 02
@ -68,7 +48,7 @@
-----------------------------------------------------------------*/
/* Find a tag in pppoe frame and return the pointer */
static inline unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
static unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
{
unsigned char *cur_ptr, *start_ptr;
unsigned short tagLen, tagType;
@ -85,16 +65,14 @@ static inline unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsign
return NULL;
}
static inline int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
static int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
{
struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
int data_len;
data_len = tag->tag_len + TAG_HDR_LEN;
if (skb_tailroom(skb) < data_len) {
_DEBUG_ERR("skb_tailroom() failed in add SID tag!\n");
data_len = be16_to_cpu(tag->tag_len) + TAG_HDR_LEN;
if (skb_tailroom(skb) < data_len)
return -1;
}
skb_put(skb, data_len);
/* have a room for new tag */
@ -125,25 +103,15 @@ static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
return 0;
}
static inline unsigned long __nat25_timeout(struct adapter *priv)
static int __nat25_has_expired(struct nat25_network_db_entry *fdb)
{
unsigned long timeout;
timeout = jiffies - NAT25_AGEING_TIME*HZ;
return timeout;
}
static inline int __nat25_has_expired(struct adapter *priv,
struct nat25_network_db_entry *fdb)
{
if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv)))
if (time_before_eq(fdb->ageing_timer, jiffies - NAT25_AGEING_TIME * HZ))
return 1;
return 0;
}
static inline void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr,
static void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr,
unsigned int *ipAddr)
{
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
@ -152,38 +120,8 @@ static inline void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr
memcpy(networkAddr+7, (unsigned char *)ipAddr, 4);
}
static inline void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr,
unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr)
{
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
networkAddr[0] = NAT25_IPX;
memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
memcpy(networkAddr+5, ipxNodeAddr, 6);
}
static inline void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr,
unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr)
{
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
networkAddr[0] = NAT25_IPX;
memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
memcpy(networkAddr+5, (unsigned char *)ipxSocketAddr, 2);
}
static inline void __nat25_generate_apple_network_addr(unsigned char *networkAddr,
unsigned short *network, unsigned char *node)
{
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
networkAddr[0] = NAT25_APPLE;
memcpy(networkAddr+1, (unsigned char *)network, 2);
networkAddr[3] = *node;
}
static inline void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr,
unsigned char *ac_mac, unsigned short *sid)
static void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr,
unsigned char *ac_mac, __be16 *sid)
{
memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
@ -222,9 +160,6 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
if (len >= 8) {
mac = scan_tlv(&data[8], len-8, 1, 1);
if (mac) {
_DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
memcpy(mac, replace_mac, 6);
return 1;
}
@ -233,9 +168,6 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
if (len >= 16) {
mac = scan_tlv(&data[16], len-16, 1, 1);
if (mac) {
_DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
memcpy(mac, replace_mac, 6);
return 1;
}
@ -244,9 +176,6 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
if (len >= 24) {
mac = scan_tlv(&data[24], len-24, 1, 1);
if (mac) {
_DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
memcpy(mac, replace_mac, 6);
return 1;
}
@ -255,9 +184,6 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
if (len >= 24) {
mac = scan_tlv(&data[24], len-24, 2, 1);
if (mac) {
_DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
memcpy(mac, replace_mac, 6);
return 1;
}
@ -266,9 +192,6 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
if (len >= 40) {
mac = scan_tlv(&data[40], len-40, 2, 1);
if (mac) {
_DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
memcpy(mac, replace_mac, 6);
return 1;
}
@ -277,7 +200,7 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char
return 0;
}
static inline int __nat25_network_hash(unsigned char *networkAddr)
static int __nat25_network_hash(unsigned char *networkAddr)
{
if (networkAddr[0] == NAT25_IPV4) {
unsigned long x;
@ -324,77 +247,27 @@ static inline int __nat25_network_hash(unsigned char *networkAddr)
}
}
static inline void __network_hash_link(struct adapter *priv,
static void __network_hash_link(struct adapter *priv,
struct nat25_network_db_entry *ent, int hash)
{
/* Caller must spin_lock already! */
ent->next_hash = priv->nethash[hash];
if (ent->next_hash != NULL)
if (ent->next_hash)
ent->next_hash->pprev_hash = &ent->next_hash;
priv->nethash[hash] = ent;
ent->pprev_hash = &priv->nethash[hash];
}
static inline void __network_hash_unlink(struct nat25_network_db_entry *ent)
static void __network_hash_unlink(struct nat25_network_db_entry *ent)
{
/* Caller must spin_lock already! */
*(ent->pprev_hash) = ent->next_hash;
if (ent->next_hash != NULL)
*ent->pprev_hash = ent->next_hash;
if (ent->next_hash)
ent->next_hash->pprev_hash = ent->pprev_hash;
ent->next_hash = NULL;
ent->pprev_hash = NULL;
}
static int __nat25_db_network_lookup_and_replace(struct adapter *priv,
struct sk_buff *skb, unsigned char *networkAddr)
{
struct nat25_network_db_entry *db;
spin_lock_bh(&priv->br_ext_lock);
db = priv->nethash[__nat25_network_hash(networkAddr)];
while (db != NULL) {
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
if (!__nat25_has_expired(priv, db)) {
/* replace the destination mac address */
memcpy(skb->data, db->macAddr, ETH_ALEN);
atomic_inc(&db->use_count);
DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
"%02x%02x%02x%02x%02x%02x\n",
db->macAddr[0],
db->macAddr[1],
db->macAddr[2],
db->macAddr[3],
db->macAddr[4],
db->macAddr[5],
db->networkAddr[0],
db->networkAddr[1],
db->networkAddr[2],
db->networkAddr[3],
db->networkAddr[4],
db->networkAddr[5],
db->networkAddr[6],
db->networkAddr[7],
db->networkAddr[8],
db->networkAddr[9],
db->networkAddr[10],
db->networkAddr[11],
db->networkAddr[12],
db->networkAddr[13],
db->networkAddr[14],
db->networkAddr[15],
db->networkAddr[16]);
}
spin_unlock_bh(&priv->br_ext_lock);
return 1;
}
db = db->next_hash;
}
spin_unlock_bh(&priv->br_ext_lock);
return 0;
}
static void __nat25_db_network_insert(struct adapter *priv,
unsigned char *macAddr, unsigned char *networkAddr)
{
@ -404,7 +277,7 @@ static void __nat25_db_network_insert(struct adapter *priv,
spin_lock_bh(&priv->br_ext_lock);
hash = __nat25_network_hash(networkAddr);
db = priv->nethash[hash];
while (db != NULL) {
while (db) {
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
memcpy(db->macAddr, macAddr, ETH_ALEN);
db->ageing_timer = jiffies;
@ -413,8 +286,8 @@ static void __nat25_db_network_insert(struct adapter *priv,
}
db = db->next_hash;
}
db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db));
if (db == NULL) {
db = kmalloc(sizeof(*db), GFP_ATOMIC);
if (!db) {
spin_unlock_bh(&priv->br_ext_lock);
return;
}
@ -428,10 +301,6 @@ static void __nat25_db_network_insert(struct adapter *priv,
spin_unlock_bh(&priv->br_ext_lock);
}
static void __nat25_db_print(struct adapter *priv)
{
}
/*
* NAT2.5 interface
*/
@ -445,7 +314,7 @@ void nat25_db_cleanup(struct adapter *priv)
for (i = 0; i < NAT25_HASH_SIZE; i++) {
struct nat25_network_db_entry *f;
f = priv->nethash[i];
while (f != NULL) {
while (f) {
struct nat25_network_db_entry *g;
g = f->next_hash;
@ -472,11 +341,11 @@ void nat25_db_expire(struct adapter *priv)
struct nat25_network_db_entry *f;
f = priv->nethash[i];
while (f != NULL) {
while (f) {
struct nat25_network_db_entry *g;
g = f->next_hash;
if (__nat25_has_expired(priv, f)) {
if (__nat25_has_expired(f)) {
if (atomic_dec_and_test(&f->use_count)) {
if (priv->scdb_entry == f) {
memset(priv->scdb_mac, 0, ETH_ALEN);
@ -499,7 +368,7 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
unsigned int tmp;
if (skb == NULL)
if (!skb)
return -1;
if ((method <= NAT25_MIN) || (method >= NAT25_MAX))
@ -513,10 +382,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
if (protocol == ETH_P_IP) {
struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
if (((unsigned char *)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) {
DEBUG_WARN("NAT25: malformed IP packet !\n");
if (((unsigned char *)(iph) + (iph->ihl << 2)) >= (skb->data + ETH_HLEN + skb->len))
return -1;
}
switch (method) {
case NAT25_CHECK:
@ -527,33 +394,9 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
if (iph->saddr == 0)
return 0;
tmp = be32_to_cpu(iph->saddr);
DEBUG_INFO("NAT25: Insert IP, SA =%08x, DA =%08x\n", tmp, iph->daddr);
__nat25_generate_ipv4_network_addr(networkAddr, &tmp);
/* record source IP address and , source mac address into db */
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
return 0;
case NAT25_LOOKUP:
DEBUG_INFO("NAT25: Lookup IP, SA =%08x, DA =%08x\n", iph->saddr, iph->daddr);
tmp = be32_to_cpu(iph->daddr);
__nat25_generate_ipv4_network_addr(networkAddr, &tmp);
if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
if (*((unsigned char *)&iph->daddr + 3) == 0xff) {
/* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */
DEBUG_INFO("NAT25: Set DA as boardcast\n");
memset(skb->data, 0xff, ETH_ALEN);
} else {
/* forward unknow IP packet to upper TCP/IP */
DEBUG_INFO("NAT25: Replace DA with BR's MAC\n");
if ((*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0) {
printk("Re-init netdev_br_init() due to br_mac == 0!\n");
netdev_br_init(priv->pnetdev);
}
memcpy(skb->data, priv->br_mac, ETH_ALEN);
}
}
return 0;
default:
return -1;
@ -564,244 +407,25 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
/*---------------------------------------------------*/
struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
unsigned char *arp_ptr = (unsigned char *)(arp + 1);
unsigned int *sender, *target;
unsigned int *sender;
if (arp->ar_pro != __constant_htons(ETH_P_IP)) {
DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro));
if (arp->ar_pro != htons(ETH_P_IP))
return -1;
}
switch (method) {
case NAT25_CHECK:
return 0; /* skb_copy for all ARP frame */
case NAT25_INSERT:
DEBUG_INFO("NAT25: Insert ARP, MAC =%02x%02x%02x%02x%02x%02x\n", arp_ptr[0],
arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]);
/* change to ARP sender mac address to wlan STA address */
memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN);
arp_ptr += arp->ar_hln;
sender = (unsigned int *)arp_ptr;
__nat25_generate_ipv4_network_addr(networkAddr, sender);
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
return 0;
case NAT25_LOOKUP:
DEBUG_INFO("NAT25: Lookup ARP\n");
arp_ptr += arp->ar_hln;
sender = (unsigned int *)arp_ptr;
arp_ptr += (arp->ar_hln + arp->ar_pln);
target = (unsigned int *)arp_ptr;
__nat25_generate_ipv4_network_addr(networkAddr, target);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
/* change to ARP target mac address to Lookup result */
arp_ptr = (unsigned char *)(arp + 1);
arp_ptr += (arp->ar_hln + arp->ar_pln);
memcpy(arp_ptr, skb->data, ETH_ALEN);
return 0;
default:
return -1;
}
} else if ((protocol == ETH_P_IPX) ||
(protocol <= ETH_FRAME_LEN)) {
/*---------------------------------------------------*/
/* Handle IPX and Apple Talk frame */
/*---------------------------------------------------*/
unsigned char ipx_header[2] = {0xFF, 0xFF};
struct ipxhdr *ipx = NULL;
struct elapaarp *ea = NULL;
struct ddpehdr *ddp = NULL;
unsigned char *framePtr = skb->data + ETH_HLEN;
if (protocol == ETH_P_IPX) {
DEBUG_INFO("NAT25: Protocol = IPX (Ethernet II)\n");
ipx = (struct ipxhdr *)framePtr;
} else if (protocol <= ETH_FRAME_LEN) {
if (!memcmp(ipx_header, framePtr, 2)) {
DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.3)\n");
ipx = (struct ipxhdr *)framePtr;
} else {
unsigned char ipx_8022_type = 0xE0;
unsigned char snap_8022_type = 0xAA;
if (*framePtr == snap_8022_type) {
unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */
unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */
unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */
framePtr += 3; /* eliminate the 802.2 header */
if (!memcmp(ipx_snap_id, framePtr, 5)) {
framePtr += 5; /* eliminate the SNAP header */
DEBUG_INFO("NAT25: Protocol = IPX (Ethernet SNAP)\n");
ipx = (struct ipxhdr *)framePtr;
} else if (!memcmp(aarp_snap_id, framePtr, 5)) {
framePtr += 5; /* eliminate the SNAP header */
ea = (struct elapaarp *)framePtr;
} else if (!memcmp(ddp_snap_id, framePtr, 5)) {
framePtr += 5; /* eliminate the SNAP header */
ddp = (struct ddpehdr *)framePtr;
} else {
DEBUG_WARN("NAT25: Protocol = Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0],
framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
return -1;
}
} else if (*framePtr == ipx_8022_type) {
framePtr += 3; /* eliminate the 802.2 header */
if (!memcmp(ipx_header, framePtr, 2)) {
DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.2)\n");
ipx = (struct ipxhdr *)framePtr;
} else {
return -1;
}
} else {
return -1;
}
}
} else {
return -1;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
/* IPX */
if (ipx != NULL) {
switch (method) {
case NAT25_CHECK:
if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
DEBUG_INFO("NAT25: Check IPX skb_copy\n");
return 0;
case NAT25_INSERT:
DEBUG_INFO("NAT25: Insert IPX, Dest =%08x,%02x%02x%02x%02x%02x%02x,%04x Source =%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
ipx->ipx_dest.net,
ipx->ipx_dest.node[0],
ipx->ipx_dest.node[1],
ipx->ipx_dest.node[2],
ipx->ipx_dest.node[3],
ipx->ipx_dest.node[4],
ipx->ipx_dest.node[5],
ipx->ipx_dest.sock,
ipx->ipx_source.net,
ipx->ipx_source.node[0],
ipx->ipx_source.node[1],
ipx->ipx_source.node[2],
ipx->ipx_source.node[3],
ipx->ipx_source.node[4],
ipx->ipx_source.node[5],
ipx->ipx_source.sock);
if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) {
DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n");
__nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock);
/* change IPX source node addr to wlan STA address */
memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN);
} else {
__nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node);
}
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
return 0;
case NAT25_LOOKUP:
if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) {
DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n");
__nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
/* replace IPX destination node addr with Lookup destination MAC addr */
memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN);
} else {
__nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
}
return 0;
default:
return -1;
}
} else if (ea != NULL) {
/* Sanity check fields. */
if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n");
return -1;
}
switch (method) {
case NAT25_CHECK:
return 0;
case NAT25_INSERT:
/* change to AARP source mac address to wlan STA address */
memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN);
DEBUG_INFO("NAT25: Insert AARP, Source =%d,%d Destination =%d,%d\n",
ea->pa_src_net,
ea->pa_src_node,
ea->pa_dst_net,
ea->pa_dst_node);
__nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node);
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
return 0;
case NAT25_LOOKUP:
DEBUG_INFO("NAT25: Lookup AARP, Source =%d,%d Destination =%d,%d\n",
ea->pa_src_net,
ea->pa_src_node,
ea->pa_dst_net,
ea->pa_dst_node);
__nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
/* change to AARP destination mac address to Lookup result */
memcpy(ea->hw_dst, skb->data, ETH_ALEN);
return 0;
default:
return -1;
}
} else if (ddp != NULL) {
switch (method) {
case NAT25_CHECK:
return -1;
case NAT25_INSERT:
DEBUG_INFO("NAT25: Insert DDP, Source =%d,%d Destination =%d,%d\n",
ddp->deh_snet,
ddp->deh_snode,
ddp->deh_dnet,
ddp->deh_dnode);
__nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode);
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
return 0;
case NAT25_LOOKUP:
DEBUG_INFO("NAT25: Lookup DDP, Source =%d,%d Destination =%d,%d\n",
ddp->deh_snet,
ddp->deh_snode,
ddp->deh_dnet,
ddp->deh_dnode);
__nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
return 0;
default:
return -1;
}
}
#endif
return -1;
} else if ((protocol == ETH_P_PPP_DISC) ||
(protocol == ETH_P_PPP_SES)) {
/*---------------------------------------------------*/
@ -827,18 +451,19 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
if (pOldTag) { /* if SID existed, copy old value and delete it */
old_tag_len = ntohs(pOldTag->tag_len);
if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) {
DEBUG_ERR("SID tag length too long!\n");
if (old_tag_len +
TAG_HDR_LEN +
MAGIC_CODE_LEN +
RTL_RELAY_TAG_LEN >
sizeof(tag_buf))
return -1;
}
memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN,
pOldTag->tag_data, old_tag_len);
if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) {
DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n");
if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0)
return -1;
}
ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len);
}
@ -853,15 +478,12 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
/* Add relay tag */
if (__nat25_add_pppoe_tag(skb, tag) < 0)
return -1;
DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n",
(ph->code == PADI_CODE ? "PADI" : "PADR"));
} else { /* not add relay tag */
if (priv->pppoe_connection_in_progress &&
memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) {
DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n");
memcmp(skb->data + ETH_ALEN,
priv->pppoe_addr,
ETH_ALEN))
return -2;
}
if (priv->pppoe_connection_in_progress == 0)
memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN);
@ -872,84 +494,16 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
return -1;
}
} else { /* session phase */
DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name);
__nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid));
__nat25_generate_pppoe_network_addr(networkAddr, skb->data, &ph->sid);
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
if (!priv->ethBrExtInfo.addPPPoETag &&
priv->pppoe_connection_in_progress &&
!memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN))
priv->pppoe_connection_in_progress = 0;
}
return 0;
case NAT25_LOOKUP:
if (ph->code == PADO_CODE || ph->code == PADS_CODE) {
if (priv->ethBrExtInfo.addPPPoETag) {
struct pppoe_tag *tag;
unsigned char *ptr;
unsigned short tagType, tagLen;
int offset = 0;
ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
if (ptr == NULL) {
DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n");
return -1;
}
tag = (struct pppoe_tag *)ptr;
tagType = (unsigned short)((ptr[0] << 8) + ptr[1]);
tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]);
if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) {
DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen);
return -1;
}
pMagic = (unsigned short *)tag->tag_data;
if (ntohs(*pMagic) != MAGIC_CODE) {
DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n",
(ph->code == PADO_CODE ? "PADO" : "PADS"));
return -1;
}
memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN);
if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN)
offset = TAG_HDR_LEN;
if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) {
DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n");
return -1;
}
ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset));
if (offset > 0)
tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN);
DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n",
(ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name);
} else { /* not add relay tag */
if (!priv->pppoe_connection_in_progress) {
DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n");
return -1;
}
memcpy(skb->data, priv->pppoe_addr, ETH_ALEN);
priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
}
} else {
if (ph->sid != 0) {
DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name);
__nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid));
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
__nat25_db_print(priv);
} else {
return -1;
}
}
return 0;
default:
return -1;
}
@ -962,8 +516,6 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
return -1;
case NAT25_INSERT:
return 0;
case NAT25_LOOKUP:
return 0;
default:
return -1;
}
@ -976,8 +528,6 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
return -1;
case NAT25_INSERT:
return 0;
case NAT25_LOOKUP:
return 0;
default:
return -1;
}
@ -987,10 +537,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
/*------------------------------------------------*/
struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
if (sizeof(*iph) >= (skb->len - ETH_HLEN)) {
DEBUG_WARN("NAT25: malformed IPv6 packet !\n");
if (sizeof(*iph) >= (skb->len - ETH_HLEN))
return -1;
}
switch (method) {
case NAT25_CHECK:
@ -998,17 +546,9 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
return 0;
return -1;
case NAT25_INSERT:
DEBUG_INFO("NAT25: Insert IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
" DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) {
__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr);
__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
__nat25_db_print(priv);
if (iph->nexthdr == IPPROTO_ICMPV6 &&
skb->len > (ETH_HLEN + sizeof(*iph) + 4)) {
@ -1024,15 +564,6 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
}
}
return 0;
case NAT25_LOOKUP:
DEBUG_INFO("NAT25: Lookup IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x, DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr);
__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
return 0;
default:
return -1;
}
@ -1040,67 +571,6 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
return -1;
}
int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb)
{
if (!(skb->data[0] & 1)) {
int is_vlan_tag = 0, i, retval = 0;
unsigned short vlan_hdr = 0;
unsigned short protocol;
protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN)));
if (protocol == ETH_P_8021Q) {
is_vlan_tag = 1;
vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2));
for (i = 0; i < 6; i++)
*((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2));
skb_pull(skb, 4);
}
if (!priv->ethBrExtInfo.nat25_disable) {
spin_lock_bh(&priv->br_ext_lock);
/*
* This function look up the destination network address from
* the NAT2.5 database. Return value = -1 means that the
* corresponding network protocol is NOT support.
*/
if (!priv->ethBrExtInfo.nat25sc_disable &&
(be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_IP) &&
!memcmp(priv->scdb_ip, skb->data+ETH_HLEN+16, 4)) {
memcpy(skb->data, priv->scdb_mac, ETH_ALEN);
spin_unlock_bh(&priv->br_ext_lock);
} else {
spin_unlock_bh(&priv->br_ext_lock);
retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
}
} else {
if (((be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_IP) &&
!memcmp(priv->br_ip, skb->data+ETH_HLEN+16, 4)) ||
((be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_ARP) &&
!memcmp(priv->br_ip, skb->data+ETH_HLEN+24, 4))) {
/* for traffic to upper TCP/IP */
retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
}
}
if (is_vlan_tag) {
skb_push(skb, 4);
for (i = 0; i < 6; i++)
*((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
*((__be16 *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q);
*((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr;
}
if (retval == -1) {
/* DEBUG_ERR("NAT25: Lookup fail!\n"); */
return -1;
}
}
return 0;
}
#define SERVER_PORT 67
#define CLIENT_PORT 68
#define DHCP_MAGIC 0x63825363
@ -1112,22 +582,22 @@ struct dhcpMessage {
u_int8_t hlen;
u_int8_t hops;
u_int32_t xid;
u_int16_t secs;
u_int16_t flags;
u_int32_t ciaddr;
u_int32_t yiaddr;
u_int32_t siaddr;
u_int32_t giaddr;
__be16 secs;
__be16 flags;
__be32 ciaddr;
__be32 yiaddr;
__be32 siaddr;
__be32 giaddr;
u_int8_t chaddr[16];
u_int8_t sname[64];
u_int8_t file[128];
u_int32_t cookie;
__be32 cookie;
u_int8_t options[308]; /* 312 - cookie */
};
void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb)
{
if (skb == NULL)
if (!skb)
return;
if (!priv->ethBrExtInfo.dhcp_bcst_disable) {
@ -1150,7 +620,6 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb)
/* if not broadcast */
register int sum = 0;
DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n");
/* or BROADCAST flag */
dhcph->flags |= htons(BROADCAST_FLAG);
/* recalculate checksum */
@ -1167,8 +636,7 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb)
}
}
void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr,
unsigned char *ipAddr)
void *scdb_findEntry(struct adapter *priv, unsigned char *ipAddr)
{
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
struct nat25_network_db_entry *db;
@ -1177,7 +645,7 @@ void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr,
__nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr);
hash = __nat25_network_hash(networkAddr);
db = priv->nethash[hash];
while (db != NULL) {
while (db) {
if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
return (void *)db;
}

File diff suppressed because it is too large Load diff

View file

@ -1,943 +0,0 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_DEBUG_C_
#include <rtw_debug.h>
#include <rtw_version.h>
int proc_get_drv_version(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
int len = 0;
len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION);
*eof = 1;
return len;
}
int proc_get_write_reg(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
*eof = 1;
return 0;
}
int proc_set_write_reg(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 addr, val, len;
if (count < 3) {
DBG_88E("argument size is less than 3\n");
return -EFAULT;
}
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
int num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
if (num != 3) {
DBG_88E("invalid write_reg parameter!\n");
return count;
}
switch (len) {
case 1:
rtw_write8(padapter, addr, (u8)val);
break;
case 2:
rtw_write16(padapter, addr, (u16)val);
break;
case 4:
rtw_write32(padapter, addr, val);
break;
default:
DBG_88E("error write length =%d", len);
break;
}
}
return count;
}
static u32 proc_get_read_addr = 0xeeeeeeee;
static u32 proc_get_read_len = 0x4;
int proc_get_read_reg(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
if (proc_get_read_addr == 0xeeeeeeee) {
*eof = 1;
return len;
}
switch (proc_get_read_len) {
case 1:
len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
break;
case 2:
len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
break;
case 4:
len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
break;
}
*eof = 1;
return len;
}
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;
}
int proc_get_fwstate(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv));
*eof = 1;
return len;
}
int proc_get_sec_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct security_priv *psecuritypriv = &padapter->securitypriv;
int len = 0;
len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
*eof = 1;
return len;
}
int proc_get_mlmext_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
int len = 0;
len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
*eof = 1;
return len;
}
int proc_get_qos_option(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option);
*eof = 1;
return len;
}
int proc_get_ht_option(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option);
*eof = 1;
return len;
}
int proc_get_rf_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
int len = 0;
len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n",
pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
*eof = 1;
return len;
}
int proc_get_ap_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct sta_info *psta;
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
struct sta_priv *pstapriv = &padapter->stapriv;
int len = 0;
psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
if (psta) {
int i;
struct recv_reorder_ctrl *preorder_ctrl;
len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid);
len += snprintf(page + len, count - len, "sta's macaddr:%pM\n", psta->hwaddr);
len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
for (i = 0; i < 16; i++) {
preorder_ctrl = &psta->recvreorder_ctrl[i];
if (preorder_ctrl->enable)
len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
}
} else {
len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr: %pM\n", cur_network->network.MacAddress);
}
*eof = 1;
return len;
}
int proc_get_adapter_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n",
padapter->bSurpriseRemoved, padapter->bDriverStopped);
*eof = 1;
return len;
}
int proc_get_trx_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct recv_priv *precvpriv = &padapter->recvpriv;
int len = 0;
len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d, free_ext_xmitbuf_cnt=%d, free_recvframe_cnt=%d\n",
pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt, precvpriv->free_recvframe_cnt);
len += snprintf(page + len, count - len, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
*eof = 1;
return len;
}
int proc_get_mac_reg_dump1(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_mac_reg_dump2(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
memset(page, 0, count);
for (i = 0x300; i < 0x600; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_mac_reg_dump3(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
for (i = 0x600; i < 0x800; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_bb_reg_dump1(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0x800; i < 0xB00; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_bb_reg_dump2(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xB00; i < 0xE00; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_bb_reg_dump3(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1;
len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
for (i = 0xE00; i < 0x1000; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_rf_reg_dump1(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1, path;
u32 value;
len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
path = 1;
len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
for (i = 0; i < 0xC0; i++) {
value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x ", i);
len += snprintf(page + len, count - len, " 0x%08x ", value);
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_rf_reg_dump2(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1, path;
u32 value;
len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
path = 1;
len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
for (i = 0xC0; i < 0x100; i++) {
value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x ", i);
len += snprintf(page + len, count - len, " 0x%08x ", value);
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_rf_reg_dump3(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1, path;
u32 value;
len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
path = 2;
len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
for (i = 0; i < 0xC0; i++) {
value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x ", i);
len += snprintf(page + len, count - len, " 0x%08x ", value);
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_rf_reg_dump4(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
int i, j = 1, path;
u32 value;
len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
path = 2;
len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
for (i = 0xC0; i < 0x100; i++) {
value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x ", i);
len += snprintf(page + len, count - len, " 0x%08x ", value);
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
*eof = 1;
return len;
}
int proc_get_rx_signal(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
len = snprintf(page + len, count,
"rssi:%d\n"
"rxpwdb:%d\n"
"signal_strength:%u\n"
"signal_qual:%u\n"
"noise:%u\n",
padapter->recvpriv.rssi,
padapter->recvpriv.rxpwdb,
padapter->recvpriv.signal_strength,
padapter->recvpriv.signal_qual,
padapter->recvpriv.noise
);
*eof = 1;
return len;
}
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;
}
int proc_get_ht_enable(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct registry_priv *pregpriv = &padapter->registrypriv;
int len = 0;
if (pregpriv)
len += snprintf(page + len, count - len,
"%d\n",
pregpriv->ht_enable
);
*eof = 1;
return len;
}
int proc_set_ht_enable(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);
struct registry_priv *pregpriv = &padapter->registrypriv;
char tmp[32];
s32 mode = 0;
if (count < 1)
return -EFAULT;
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
if (pregpriv) {
pregpriv->ht_enable = mode;
pr_info("ht_enable=%d\n", pregpriv->ht_enable);
}
}
return count;
}
int proc_get_cbw40_enable(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct registry_priv *pregpriv = &padapter->registrypriv;
int len = 0;
if (pregpriv)
len += snprintf(page + len, count - len,
"%d\n",
pregpriv->cbw40_enable
);
*eof = 1;
return len;
}
int proc_set_cbw40_enable(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);
struct registry_priv *pregpriv = &padapter->registrypriv;
char tmp[32];
s32 mode = 0;
if (count < 1)
return -EFAULT;
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
if (pregpriv) {
pregpriv->cbw40_enable = mode;
pr_info("cbw40_enable=%d\n", mode);
}
}
return count;
}
int proc_get_ampdu_enable(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct registry_priv *pregpriv = &padapter->registrypriv;
int len = 0;
if (pregpriv)
len += snprintf(page + len, count - len,
"%d\n",
pregpriv->ampdu_enable
);
*eof = 1;
return len;
}
int proc_set_ampdu_enable(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);
struct registry_priv *pregpriv = &padapter->registrypriv;
char tmp[32];
s32 mode = 0;
if (count < 1)
return -EFAULT;
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
if (pregpriv) {
pregpriv->ampdu_enable = mode;
pr_info("ampdu_enable=%d\n", mode);
}
}
return count;
}
int proc_get_two_path_rssi(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
int len = 0;
if (padapter)
len += snprintf(page + len, count - len,
"%d %d\n",
padapter->recvpriv.RxRssi[0],
padapter->recvpriv.RxRssi[1]
);
*eof = 1;
return len;
}
int proc_get_rx_stbc(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct registry_priv *pregpriv = &padapter->registrypriv;
int len = 0;
if (pregpriv)
len += snprintf(page + len, count - len,
"%d\n",
pregpriv->rx_stbc
);
*eof = 1;
return len;
}
int proc_set_rx_stbc(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);
struct registry_priv *pregpriv = &padapter->registrypriv;
char tmp[32];
u32 mode = 0;
if (count < 1)
return -EFAULT;
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
if (pregpriv) {
pregpriv->rx_stbc = mode;
printk("rx_stbc=%d\n", mode);
}
}
return count;
}
int proc_get_rssi_disp(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
*eof = 1;
return 0;
}
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;
}
#ifdef CONFIG_88EU_AP_MODE
int proc_get_all_sta_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct sta_info *psta;
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct sta_priv *pstapriv = &padapter->stapriv;
int i, j;
struct list_head *plist, *phead;
struct recv_reorder_ctrl *preorder_ctrl;
int len = 0;
len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
spin_lock_bh(&pstapriv->sta_hash_lock);
for (i = 0; i < NUM_STA; i++) {
phead = &(pstapriv->sta_hash[i]);
plist = phead->next;
while (phead != plist) {
psta = container_of(plist, struct sta_info, hash_list);
plist = plist->next;
len += snprintf(page + len, count - len, "sta's macaddr: %pM\n", psta->hwaddr);
len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len);
len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability);
len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags);
len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk);
len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info);
len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
for (j = 0; j < 16; j++) {
preorder_ctrl = &psta->recvreorder_ctrl[j];
if (preorder_ctrl->enable)
len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
}
}
}
spin_unlock_bh(&pstapriv->sta_hash_lock);
*eof = 1;
return len;
}
#endif
int proc_get_best_channel(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
int len = 0;
u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
if (pmlmeext->channel_set[i].ChannelNum == 1)
index_24G = i;
if (pmlmeext->channel_set[i].ChannelNum == 36)
index_5G = i;
}
for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
/* 2.4G */
if (pmlmeext->channel_set[i].ChannelNum == 6) {
if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) {
index_24G = i;
best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
}
}
/* 5G */
if (pmlmeext->channel_set[i].ChannelNum >= 36 &&
pmlmeext->channel_set[i].ChannelNum < 140) {
/* Find primary channel */
if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) &&
(pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
index_5G = i;
best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
}
}
if (pmlmeext->channel_set[i].ChannelNum >= 149 &&
pmlmeext->channel_set[i].ChannelNum < 165) {
/* find primary channel */
if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) &&
(pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
index_5G = i;
best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
}
}
/* debug */
len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
}
len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G);
len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);
*eof = 1;
return len;
}

View file

@ -1,158 +1,12 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#define _RTW_EFUSE_C_
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_efuse.h>
/*------------------------Define local variable------------------------------*/
u8 fakeEfuseBank;
u32 fakeEfuseUsedBytes;
u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
u32 BTEfuseUsedBytes;
u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
u32 fakeBTEfuseUsedBytes;
u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
/*------------------------Define local variable------------------------------*/
/* */
#define REG_EFUSE_CTRL 0x0030
#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
/* */
bool
Efuse_Read1ByteFromFakeContent(
struct adapter *pAdapter,
u16 Offset,
u8 *Value);
bool
Efuse_Read1ByteFromFakeContent(
struct adapter *pAdapter,
u16 Offset,
u8 *Value)
{
if (Offset >= EFUSE_MAX_HW_SIZE)
return false;
if (fakeEfuseBank == 0)
*Value = fakeEfuseContent[Offset];
else
*Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
return true;
}
static bool
Efuse_Write1ByteToFakeContent(
struct adapter *pAdapter,
u16 Offset,
u8 Value)
{
if (Offset >= EFUSE_MAX_HW_SIZE)
return false;
if (fakeEfuseBank == 0) {
fakeEfuseContent[Offset] = Value;
} else {
fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
}
return true;
}
/*-----------------------------------------------------------------------------
* Function: Efuse_PowerSwitch
*
* Overview: When we want to enable write operation, we should change to
* pwr on state. When we stop write, we should switch to 500k mode
* and disable LDO 2.5V.
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/17/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
void
Efuse_PowerSwitch(
struct adapter *pAdapter,
u8 write,
u8 PwrState)
{
pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState);
}
/*-----------------------------------------------------------------------------
* Function: efuse_GetCurrentSize
*
* Overview: Get current efuse size!!!
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/16/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
u16
Efuse_GetCurrentSize(
struct adapter *pAdapter,
u8 efuseType,
bool pseudo)
{
u16 ret = 0;
ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo);
return ret;
}
/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
u8
Efuse_CalculateWordCnts(u8 word_en)
{
u8 word_cnts = 0;
if (!(word_en & BIT(0)))
word_cnts++; /* 0 : write enable */
if (!(word_en & BIT(1)))
word_cnts++;
if (!(word_en & BIT(2)))
word_cnts++;
if (!(word_en & BIT(3)))
word_cnts++;
return word_cnts;
}
#include "../include/osdep_service.h"
#include "../include/drv_types.h"
#include "../include/rtw_efuse.h"
#include "../include/rtl8188e_hal.h"
/* */
/* Description: */
@ -169,26 +23,20 @@ void
ReadEFuseByte(
struct adapter *Adapter,
u16 _offset,
u8 *pbuf,
bool pseudo)
u8 *pbuf)
{
u32 value32;
u8 readbyte;
u16 retry;
if (pseudo) {
Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
return;
}
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
/* Check bit 32 read-ready */
retry = 0;
@ -202,616 +50,12 @@ ReadEFuseByte(
/* This fix the problem that Efuse read error in high temperature condition. */
/* Designer says that there shall be some delay after ready bit is set, or the */
/* result will always stay on last data we read. */
rtw_udelay_os(50);
udelay(50);
value32 = rtw_read32(Adapter, EFUSE_CTRL);
*pbuf = (u8)(value32 & 0xff);
}
/* */
/* Description: */
/* 1. Execute E-Fuse read byte operation according as map offset and */
/* save to E-Fuse table. */
/* 2. Referred from SD1 Richard. */
/* */
/* Assumption: */
/* 1. Boot from E-Fuse and successfully auto-load. */
/* 2. PASSIVE_LEVEL (USB interface) */
/* */
/* Created by Roger, 2008.10.21. */
/* */
/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */
/* 2. Add efuse utilization collect. */
/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */
/* write addr must be after sec5. */
/* */
static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
{
Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
}
void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
)
{
pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo);
}
/*-----------------------------------------------------------------------------
* Function: EFUSE_Read1Byte
*
* Overview: Copy from WMAC fot EFUSE read 1 byte.
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 09/23/2008 MHC Copy from WMAC.
*
*---------------------------------------------------------------------------*/
u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
{
u8 data;
u8 Bytetemp = {0x00};
u8 temp = {0x00};
u32 k = 0;
u16 contentLen = 0;
EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
if (Address < contentLen) { /* E-fuse 512Byte */
/* Write E-fuse Register address bit0~7 */
temp = Address & 0xFF;
rtw_write8(Adapter, EFUSE_CTRL+1, temp);
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
/* Write E-fuse Register address bit8~9 */
temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
rtw_write8(Adapter, EFUSE_CTRL+2, temp);
/* Write 0x30[31]= 0 */
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
temp = Bytetemp & 0x7F;
rtw_write8(Adapter, EFUSE_CTRL+3, temp);
/* Wait Write-ready (0x30[31]= 1) */
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
while (!(Bytetemp & 0x80)) {
Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
k++;
if (k == 1000) {
k = 0;
break;
}
}
data = rtw_read8(Adapter, EFUSE_CTRL);
return data;
} else {
return 0xFF;
}
} /* EFUSE_Read1Byte */
/* 11/16/2008 MH Read one byte from real Efuse. */
u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
{
u8 tmpidx = 0;
u8 result;
if (pseudo) {
result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
return result;
}
/* -----------------e-fuse reg ctrl --------------------------------- */
/* address */
rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff));
rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
(rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC));
rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */
while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
tmpidx++;
if (tmpidx < 100) {
*data = rtw_read8(pAdapter, EFUSE_CTRL);
result = true;
} else {
*data = 0xff;
result = false;
}
return result;
}
/* 11/16/2008 MH Write one byte to reald Efuse. */
u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
{
u8 tmpidx = 0;
u8 result;
if (pseudo) {
result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
return result;
}
/* -----------------e-fuse reg ctrl --------------------------------- */
/* address */
rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
rtw_write8(pAdapter, EFUSE_CTRL+2,
(rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) |
(u8)((addr>>8) & 0x03));
rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
tmpidx++;
if (tmpidx < 100)
result = true;
else
result = false;
return result;
}
int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo)
{
int ret = 0;
ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo);
return ret;
}
int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
{
int ret;
ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo);
return ret;
}
static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
{
int ret;
ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo);
return ret;
}
/*-----------------------------------------------------------------------------
* Function: efuse_WordEnableDataRead
*
* Overview: Read allowed word in current efuse section data.
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/16/2008 MHC Create Version 0.
* 11/21/2008 MHC Fix Write bug when we only enable late word.
*
*---------------------------------------------------------------------------*/
void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
{
if (!(word_en&BIT(0))) {
targetdata[0] = sourdata[0];
targetdata[1] = sourdata[1];
}
if (!(word_en&BIT(1))) {
targetdata[2] = sourdata[2];
targetdata[3] = sourdata[3];
}
if (!(word_en&BIT(2))) {
targetdata[4] = sourdata[4];
targetdata[5] = sourdata[5];
}
if (!(word_en&BIT(3))) {
targetdata[6] = sourdata[6];
targetdata[7] = sourdata[7];
}
}
u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo)
{
u8 ret = 0;
ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo);
return ret;
}
static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value)
{
return efuse_OneByteRead(padapter, address, value, false);
}
static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value)
{
return efuse_OneByteWrite(padapter, address, *value, false);
}
/*
* read/wirte raw efuse data
*/
u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data)
{
int i = 0;
u16 real_content_len = 0, max_available_size = 0;
u8 res = _FAIL ;
u8 (*rw8)(struct adapter *, u16, u8*);
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false);
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
if (start_addr > real_content_len)
return _FAIL;
if (write) {
if ((start_addr + cnts) > max_available_size)
return _FAIL;
rw8 = &efuse_write8;
} else {
rw8 = &efuse_read8;
}
Efuse_PowerSwitch(padapter, write, true);
/* e-fuse one byte read / write */
for (i = 0; i < cnts; i++) {
if (start_addr >= real_content_len) {
res = _FAIL;
break;
}
res = rw8(padapter, start_addr++, data++);
if (_FAIL == res)
break;
}
Efuse_PowerSwitch(padapter, write, false);
return res;
}
/* */
u16 efuse_GetMaxSize(struct adapter *padapter)
{
u16 max_size;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false);
return max_size;
}
/* */
u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
{
Efuse_PowerSwitch(padapter, false, true);
*size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false);
Efuse_PowerSwitch(padapter, false, false);
return _SUCCESS;
}
/* */
u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
if ((addr + cnts) > mapLen)
return _FAIL;
Efuse_PowerSwitch(padapter, false, true);
efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
Efuse_PowerSwitch(padapter, false, false);
return _SUCCESS;
}
u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u16 mapLen = 0;
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
if ((addr + cnts) > mapLen)
return _FAIL;
Efuse_PowerSwitch(padapter, false, true);
efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
Efuse_PowerSwitch(padapter, false, false);
return _SUCCESS;
}
/* */
u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u8 offset, word_en;
u8 *map;
u8 newdata[PGPKT_DATA_SIZE + 1];
s32 i, idx;
u8 ret = _SUCCESS;
u16 mapLen = 0;
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
if ((addr + cnts) > mapLen)
return _FAIL;
map = rtw_zmalloc(mapLen);
if (map == NULL)
return _FAIL;
ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
if (ret == _FAIL)
goto exit;
Efuse_PowerSwitch(padapter, true, true);
offset = (addr >> 3);
word_en = 0xF;
memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
i = addr & 0x7; /* index of one package */
idx = 0; /* data index */
if (i & 0x1) {
/* odd start */
if (data[idx] != map[addr+idx]) {
word_en &= ~BIT(i >> 1);
newdata[i-1] = map[addr+idx-1];
newdata[i] = data[idx];
}
i++;
idx++;
}
do {
for (; i < PGPKT_DATA_SIZE; i += 2) {
if (cnts == idx)
break;
if ((cnts - idx) == 1) {
if (data[idx] != map[addr+idx]) {
word_en &= ~BIT(i >> 1);
newdata[i] = data[idx];
newdata[i+1] = map[addr+idx+1];
}
idx++;
break;
} else {
if ((data[idx] != map[addr+idx]) ||
(data[idx+1] != map[addr+idx+1])) {
word_en &= ~BIT(i >> 1);
newdata[i] = data[idx];
newdata[i+1] = data[idx + 1];
}
idx += 2;
}
if (idx == cnts)
break;
}
if (word_en != 0xF) {
ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false);
DBG_88E("offset=%x\n", offset);
DBG_88E("word_en=%x\n", word_en);
for (i = 0; i < PGPKT_DATA_SIZE; i++)
DBG_88E("data=%x \t", newdata[i]);
if (ret == _FAIL)
break;
}
if (idx == cnts)
break;
offset++;
i = 0;
word_en = 0xF;
memset(newdata, 0xFF, PGPKT_DATA_SIZE);
} while (1);
Efuse_PowerSwitch(padapter, true, false);
exit:
kfree(map);
return ret;
}
/* */
u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
{
u8 offset, word_en;
u8 *map;
u8 newdata[PGPKT_DATA_SIZE + 1];
s32 i, idx;
u8 ret = _SUCCESS;
u16 mapLen = 0;
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
if ((addr + cnts) > mapLen)
return _FAIL;
map = rtw_zmalloc(mapLen);
if (map == NULL)
return _FAIL;
ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
if (ret == _FAIL)
goto exit;
Efuse_PowerSwitch(padapter, true, true);
offset = (addr >> 3);
word_en = 0xF;
memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
i = addr & 0x7; /* index of one package */
idx = 0; /* data index */
if (i & 0x1) {
/* odd start */
if (data[idx] != map[addr+idx]) {
word_en &= ~BIT(i >> 1);
newdata[i-1] = map[addr+idx-1];
newdata[i] = data[idx];
}
i++;
idx++;
}
do {
for (; i < PGPKT_DATA_SIZE; i += 2) {
if (cnts == idx)
break;
if ((cnts - idx) == 1) {
if (data[idx] != map[addr+idx]) {
word_en &= ~BIT(i >> 1);
newdata[i] = data[idx];
newdata[i+1] = map[addr+idx+1];
}
idx++;
break;
} else {
if ((data[idx] != map[addr+idx]) ||
(data[idx+1] != map[addr+idx+1])) {
word_en &= ~BIT(i >> 1);
newdata[i] = data[idx];
newdata[i+1] = data[idx + 1];
}
idx += 2;
}
if (idx == cnts)
break;
}
if (word_en != 0xF) {
DBG_88E("%s: offset=%#X\n", __func__, offset);
DBG_88E("%s: word_en=%#X\n", __func__, word_en);
DBG_88E("%s: data=", __func__);
for (i = 0; i < PGPKT_DATA_SIZE; i++)
DBG_88E("0x%02X ", newdata[i]);
DBG_88E("\n");
ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false);
if (ret == _FAIL)
break;
}
if (idx == cnts)
break;
offset++;
i = 0;
word_en = 0xF;
memset(newdata, 0xFF, PGPKT_DATA_SIZE);
} while (1);
Efuse_PowerSwitch(padapter, true, false);
exit:
kfree(map);
return ret;
}
/*-----------------------------------------------------------------------------
* Function: efuse_ShadowRead1Byte
* efuse_ShadowRead2Byte
* efuse_ShadowRead4Byte
*
* Overview: Read from efuse init map by one/two/four bytes !!!!!
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/12/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
static void
efuse_ShadowRead1Byte(
struct adapter *pAdapter,
u16 Offset,
u8 *Value)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
*Value = pEEPROM->efuse_eeprom_data[Offset];
} /* EFUSE_ShadowRead1Byte */
/* Read Two Bytes */
static void
efuse_ShadowRead2Byte(
struct adapter *pAdapter,
u16 Offset,
u16 *Value)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
*Value = pEEPROM->efuse_eeprom_data[Offset];
*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
} /* EFUSE_ShadowRead2Byte */
/* Read Four Bytes */
static void
efuse_ShadowRead4Byte(
struct adapter *pAdapter,
u16 Offset,
u32 *Value)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
*Value = pEEPROM->efuse_eeprom_data[Offset];
*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
*Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
*Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
} /* efuse_ShadowRead4Byte */
/*-----------------------------------------------------------------------------
* Function: Efuse_ReadAllMap
*
* Overview: Read All Efuse content
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/11/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
{
u16 mapLen = 0;
Efuse_PowerSwitch(pAdapter, false, true);
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
Efuse_PowerSwitch(pAdapter, false, false);
}
/*-----------------------------------------------------------------------------
* Function: EFUSE_ShadowMapUpdate
*
@ -828,45 +72,16 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
* 11/13/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
void EFUSE_ShadowMapUpdate(
struct adapter *pAdapter,
u8 efuseType,
bool pseudo)
void EFUSE_ShadowMapUpdate(struct adapter *pAdapter)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
u16 mapLen = 0;
struct eeprom_priv *pEEPROM = &pAdapter->eeprompriv;
EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
if (pEEPROM->bautoload_fail_flag) {
memset(pEEPROM->efuse_eeprom_data, 0xFF, EFUSE_MAP_LEN_88E);
return;
}
if (pEEPROM->bautoload_fail_flag)
memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
else
Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
} /* EFUSE_ShadowMapUpdate */
/*-----------------------------------------------------------------------------
* Function: EFUSE_ShadowRead
*
* Overview: Read from efuse init map !!!!!
*
* Input: NONE
*
* Output: NONE
*
* Return: NONE
*
* Revised History:
* When Who Remark
* 11/12/2008 MHC Create Version 0.
*
*---------------------------------------------------------------------------*/
void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value)
{
if (Type == 1)
efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
else if (Type == 2)
efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
else if (Type == 4)
efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
} /* EFUSE_ShadowRead */
rtl8188e_EfusePowerSwitch(pAdapter, true);
rtl8188e_ReadEFuse(pAdapter, 0, EFUSE_MAP_LEN_88E, pEEPROM->efuse_eeprom_data);
rtl8188e_EfusePowerSwitch(pAdapter, false);
}

314
core/rtw_fw.c Normal file
View file

@ -0,0 +1,314 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include <linux/firmware.h>
#include "../include/rtw_fw.h"
#define MAX_REG_BOLCK_SIZE 196
#define FW_8188E_START_ADDRESS 0x1000
#define MAX_PAGE_SIZE 4096
#define IS_FW_HEADER_EXIST(_fwhdr) \
((le16_to_cpu(_fwhdr->Signature) & 0xFFF0) == 0x92C0 || \
(le16_to_cpu(_fwhdr->Signature) & 0xFFF0) == 0x88C0 || \
(le16_to_cpu(_fwhdr->Signature) & 0xFFF0) == 0x2300 || \
(le16_to_cpu(_fwhdr->Signature) & 0xFFF0) == 0x88E0)
/* This structure must be careful with byte-ordering */
struct rt_firmware_hdr {
/* 8-byte alinment required */
/* LONG WORD 0 ---- */
__le16 Signature; /* 92C0: test chip; 92C,
* 88C0: test chip; 88C1: MP A-cut;
* 92C1: MP A-cut */
u8 Category; /* AP/NIC and USB/PCI */
u8 Function; /* Reserved for different FW function
* indcation, for further use when
* driver needs to download different
* FW for different conditions */
__le16 Version; /* FW Version */
u8 Subversion; /* FW Subversion, default 0x00 */
u16 Rsvd1;
/* LONG WORD 1 ---- */
u8 Month; /* Release time Month field */
u8 Date; /* Release time Date field */
u8 Hour; /* Release time Hour field */
u8 Minute; /* Release time Minute field */
__le16 RamCodeSize; /* The size of RAM code */
u8 Foundry;
u8 Rsvd2;
/* LONG WORD 2 ---- */
__le32 SvnIdx; /* The SVN entry index */
u32 Rsvd3;
/* LONG WORD 3 ---- */
u32 Rsvd4;
u32 Rsvd5;
};
static void fw_download_enable(struct adapter *padapter, bool enable)
{
u8 tmp;
if (enable) {
/* MCU firmware download enable. */
tmp = rtw_read8(padapter, REG_MCUFWDL);
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
tmp = rtw_read8(padapter, REG_MCUFWDL);
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
}
}
static int block_write(struct adapter *padapter, void *buffer, u32 buffSize)
{
int ret = _SUCCESS;
u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */
u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */
u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
u32 remainSize_p1 = 0, remainSize_p2 = 0;
u8 *bufferPtr = (u8 *)buffer;
u32 i = 0, offset = 0;
blockSize_p1 = MAX_REG_BOLCK_SIZE;
/* 3 Phase #1 */
blockCount_p1 = buffSize / blockSize_p1;
remainSize_p1 = buffSize % blockSize_p1;
for (i = 0; i < blockCount_p1; i++) {
ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
if (ret == _FAIL)
goto exit;
}
/* 3 Phase #2 */
if (remainSize_p1) {
offset = blockCount_p1 * blockSize_p1;
blockCount_p2 = remainSize_p1 / blockSize_p2;
remainSize_p2 = remainSize_p1 % blockSize_p2;
for (i = 0; i < blockCount_p2; i++) {
ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));
if (ret == _FAIL)
goto exit;
}
}
/* 3 Phase #3 */
if (remainSize_p2) {
offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
blockCount_p3 = remainSize_p2 / blockSize_p3;
for (i = 0; i < blockCount_p3; i++) {
ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
if (ret == _FAIL)
goto exit;
}
}
exit:
return ret;
}
static int page_write(struct adapter *padapter, u32 page, void *buffer, u32 size)
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return block_write(padapter, buffer, size);
}
static int write_fw(struct adapter *padapter, void *buffer, u32 size)
{
/* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
/* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
int ret = _SUCCESS;
u32 pageNums, remainSize;
u32 page, offset;
u8 *bufferPtr = (u8 *)buffer;
pageNums = size / MAX_PAGE_SIZE;
remainSize = size % MAX_PAGE_SIZE;
for (page = 0; page < pageNums; page++) {
offset = page * MAX_PAGE_SIZE;
ret = page_write(padapter, page, bufferPtr + offset, MAX_PAGE_SIZE);
if (ret == _FAIL)
goto exit;
}
if (remainSize) {
offset = pageNums * MAX_PAGE_SIZE;
page = pageNums;
ret = page_write(padapter, page, bufferPtr + offset, remainSize);
if (ret == _FAIL)
goto exit;
}
exit:
return ret;
}
void rtw_reset_8051(struct adapter *padapter)
{
u8 val8;
val8 = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 | (BIT(2)));
}
static int fw_free_to_go(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
/* polling CheckSum report */
do {
value32 = rtw_read32(padapter, REG_MCUFWDL);
if (value32 & FWDL_CHKSUM_RPT)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
if (counter >= POLLING_READY_TIMEOUT_COUNT)
return _FAIL;
value32 = rtw_read32(padapter, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
rtw_reset_8051(padapter);
/* polling for FW ready */
counter = 0;
do {
value32 = rtw_read32(padapter, REG_MCUFWDL);
if (value32 & WINTINI_RDY)
return _SUCCESS;
udelay(5);
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
return _FAIL;
}
static int load_firmware(struct rt_firmware *rtfw, struct device *device)
{
int ret = _SUCCESS;
const struct firmware *fw;
const char *fw_name = "rtlwifi/rtl8188eufw.bin";
int err = request_firmware(&fw, fw_name, device);
if (err) {
pr_err("Request firmware failed with error 0x%x\n", err);
ret = _FAIL;
goto exit;
}
if (!fw) {
pr_err("Firmware %s not available\n", fw_name);
ret = _FAIL;
goto exit;
}
rtfw->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (!rtfw->data) {
pr_err("Failed to allocate rtfw->data\n");
ret = _FAIL;
goto exit;
}
rtfw->size = fw->size;
exit:
release_firmware(fw);
return ret;
}
int rtl8188e_firmware_download(struct adapter *padapter)
{
int ret = _SUCCESS;
u8 write_fw_retry = 0;
u32 fwdl_start_time;
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
struct device *device = dvobj_to_dev(dvobj);
struct rt_firmware_hdr *fwhdr = NULL;
u16 fw_version, fw_subversion, fw_signature;
u8 *fw_data;
u32 fw_size;
static int log_version;
if (!dvobj->firmware.data)
ret = load_firmware(&dvobj->firmware, device);
if (ret == _FAIL) {
dvobj->firmware.data = NULL;
goto exit;
}
fw_data = dvobj->firmware.data;
fw_size = dvobj->firmware.size;
/* To Check Fw header. Added by tynli. 2009.12.04. */
fwhdr = (struct rt_firmware_hdr *)dvobj->firmware.data;
fw_version = le16_to_cpu(fwhdr->Version);
fw_subversion = fwhdr->Subversion;
fw_signature = le16_to_cpu(fwhdr->Signature);
if (!log_version++)
pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n",
DRIVER_PREFIX, fw_version, fw_subversion, fw_signature);
if (IS_FW_HEADER_EXIST(fwhdr)) {
/* Shift 32 bytes for FW header */
fw_data = fw_data + 32;
fw_size = fw_size - 32;
}
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
rtw_reset_8051(padapter);
}
fw_download_enable(padapter, true);
fwdl_start_time = jiffies;
while (1) {
/* reset the FWDL chksum */
rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_CHKSUM_RPT);
ret = write_fw(padapter, fw_data, fw_size);
if (ret == _SUCCESS ||
(rtw_get_passing_time_ms(fwdl_start_time) > 500 && write_fw_retry++ >= 3))
break;
}
fw_download_enable(padapter, false);
if (ret != _SUCCESS)
goto exit;
ret = fw_free_to_go(padapter);
if (ret != _SUCCESS)
goto exit;
exit:
return ret;
}

File diff suppressed because it is too large Load diff

View file

@ -1,323 +0,0 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
/*
The purpose of rtw_io.c
a. provides the API
b. provides the protocol engine
c. provides the software interface between caller and the hardware interface
Compiler Flag Option:
USB:
a. USE_ASYNC_IRP: Both sync/async operations are provided.
Only sync read/rtw_write_mem operations are provided.
jackson@realtek.com.tw
*/
#define _RTW_IO_C_
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_io.h>
#include <osdep_intf.h>
#include <usb_ops.h>
#define rtw_le16_to_cpu(val) le16_to_cpu(val)
#define rtw_le32_to_cpu(val) le32_to_cpu(val)
#define rtw_cpu_to_le16(val) cpu_to_le16(val)
#define rtw_cpu_to_le32(val) cpu_to_le32(val)
u8 _rtw_read8(struct adapter *adapter, u32 addr)
{
u8 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
_read8 = pintfhdl->io_ops._read8;
r_val = _read8(pintfhdl, addr);
return r_val;
}
u16 _rtw_read16(struct adapter *adapter, u32 addr)
{
u16 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
_read16 = pintfhdl->io_ops._read16;
r_val = _read16(pintfhdl, addr);
return r_val;
}
u32 _rtw_read32(struct adapter *adapter, u32 addr)
{
u32 r_val;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
_read32 = pintfhdl->io_ops._read32;
r_val = _read32(pintfhdl, addr);
return r_val;
}
int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8 = pintfhdl->io_ops._write8;
ret = _write8(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16(struct adapter *adapter, u32 addr, u16 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16 = pintfhdl->io_ops._write16;
ret = _write16(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32(struct adapter *adapter, u32 addr, u32 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32 = pintfhdl->io_ops._write32;
ret = _write32(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_writeN(struct adapter *adapter, u32 addr , u32 length , u8 *pdata)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));
int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
int ret;
_writeN = pintfhdl->io_ops._writeN;
ret = _writeN(pintfhdl, addr, length, pdata);
return RTW_STATUS_CODE(ret);
}
int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_write8_async = pintfhdl->io_ops._write8_async;
ret = _write8_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_write16_async = pintfhdl->io_ops._write16_async;
ret = _write16_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val)
{
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_write32_async = pintfhdl->io_ops._write32_async;
ret = _write32_async(pintfhdl, addr, val);
return RTW_STATUS_CODE(ret);
}
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
adapter->bDriverStopped, adapter->bSurpriseRemoved));
return;
}
_read_mem = pintfhdl->io_ops._read_mem;
_read_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_mem = pintfhdl->io_ops._write_mem;
_write_mem(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
adapter->bDriverStopped, adapter->bSurpriseRemoved));
return;
}
_read_port = pintfhdl->io_ops._read_port;
_read_port(pintfhdl, addr, cnt, pmem);
}
void _rtw_read_port_cancel(struct adapter *adapter)
{
void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
if (_read_port_cancel)
_read_port_cancel(pintfhdl);
}
u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32 ret = _SUCCESS;
_write_port = pintfhdl->io_ops._write_port;
ret = _write_port(pintfhdl, addr, cnt, pmem);
return ret;
}
u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
{
int ret = _SUCCESS;
struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
struct submit_ctx sctx;
rtw_sctx_init(&sctx, timeout_ms);
pxmitbuf->sctx = &sctx;
ret = _rtw_write_port(adapter, addr, cnt, pmem);
if (ret == _SUCCESS)
ret = rtw_sctx_wait(&sctx);
return ret;
}
void _rtw_write_port_cancel(struct adapter *adapter)
{
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
if (_write_port_cancel)
_write_port_cancel(pintfhdl);
}
int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops))
{
struct io_priv *piopriv = &padapter->iopriv;
struct intf_hdl *pintf = &piopriv->intf;
if (set_intf_ops == NULL)
return _FAIL;
piopriv->padapter = padapter;
pintf->padapter = padapter;
pintf->pintf_dev = adapter_to_dvobj(padapter);
set_intf_ops(&pintf->io_ops);
return _SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -1,44 +1,23 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include<rtw_iol.h>
#include "../include/rtw_iol.h"
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);
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;
}
if (!xmit_frame)
return NULL;
xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
if (xmitbuf == NULL) {
DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__);
if (!xmitbuf) {
rtw_free_xmitframe(pxmitpriv, xmit_frame);
xmit_frame = NULL;
goto exit;
return NULL;
}
xmit_frame->frame_tag = MGNT_FRAMETAG;
@ -52,7 +31,7 @@ struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter)
pattrib->subtype = WIFI_BEACON;
pattrib->pktlen = 0;
pattrib->last_txcmdsz = 0;
exit:
return xmit_frame;
}
@ -63,14 +42,11 @@ int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len
u32 ori_len;
buf_offset = TXDESC_OFFSET;
ori_len = buf_offset+pattrib->pktlen;
ori_len = buf_offset + pattrib->pktlen;
/* check if the io_buf can accommodate new cmds */
if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n",
__func__ , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ)
return _FAIL;
}
memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
pattrib->pktlen += cmd_len;
@ -84,21 +60,13 @@ bool rtw_IOL_applied(struct adapter *adapter)
if (1 == adapter->registrypriv.fw_iol)
return true;
if ((2 == adapter->registrypriv.fw_iol) && (!adapter_to_dvobj(adapter)->ishighspeed))
if ((2 == adapter->registrypriv.fw_iol) &&
(adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH))
return true;
return false;
}
int rtw_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
{
return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
}
int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
{
return _SUCCESS;
}
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
@ -145,7 +113,7 @@ int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr,
{
struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
cmd.address = cpu_to_le16((rf_path<<8) | ((addr) & 0xFF));
cmd.address = cpu_to_le16((rf_path << 8) | ((addr) & 0xFF));
cmd.data = cpu_to_le32(value);
if (mask != 0x000FFFFF) {
@ -181,29 +149,12 @@ int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
{
u8 is_cmd_bndy = false;
if (((pxmit_frame->attrib.pktlen+32)%256) + 8 >= 256) {
if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
rtw_IOL_append_END_cmd(pxmit_frame);
pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen+32)/256)+1)*256);
pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
is_cmd_bndy = true;
}
return is_cmd_bndy;
}
void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf)
{
int i;
int j = 1;
pr_info("###### %s ######\n", __func__);
for (i = 0; i < buf_len; i++) {
printk("%02x-", *(pbuf+i));
if (j%32 == 0)
printk("\n");
j++;
}
printk("\n");
pr_info("=============ioreg_cmd len=%d===============\n", buf_len);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,11 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#define _RTW_P2P_C_
#include <drv_types.h>
#include <rtw_p2p.h>
#include <wifi.h>
#ifdef CONFIG_88EU_P2P
#include "../include/drv_types.h"
#include "../include/rtw_p2p.h"
#include "../include/wifi.h"
static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt)
{
@ -48,9 +30,7 @@ static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
struct adapter *padapter = pwdinfo->padapter;
struct sta_priv *pstapriv = &padapter->stapriv;
DBG_88E("%s\n", __func__);
pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN);
pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_KERNEL);
pstart = pdata_attr;
pcur = pdata_attr;
@ -91,8 +71,8 @@ static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
*pcur = psta->num_of_secdev_type;
pcur++;
memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8);
pcur += psta->num_of_secdev_type*8;
memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type * 8);
pcur += psta->num_of_secdev_type * 8;
if (psta->dev_name_len > 0) {
/* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
@ -107,9 +87,9 @@ static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
pcur += psta->dev_name_len;
}
tmplen = (u8)(pcur-pstart);
tmplen = (u8)(pcur - pstart);
*pstart = (tmplen-1);
*pstart = (tmplen - 1);
attr_len += tmplen;
@ -134,17 +114,15 @@ static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
struct rtw_ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
__be32 p2poui = cpu_to_be32(P2POUI);
u8 oui_subtype = P2P_GO_DISC_REQUEST;
u8 dialogToken = 0;
DBG_88E("[%s]\n", __func__);
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
if (!pmgntframe)
return;
/* update attribute */
@ -156,7 +134,7 @@ static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
fctrl = &(pwlanhdr->frame_ctl);
fctrl = &pwlanhdr->frame_ctl;
*(fctrl) = 0;
memcpy(pwlanhdr->addr1, da, ETH_ALEN);
@ -171,10 +149,10 @@ static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
/* Build P2P action frame header */
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
/* there is no IE in this P2P action frame */
@ -191,8 +169,8 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
struct rtw_ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
u8 action = P2P_PUB_ACTION_ACTION;
__be32 p2poui = cpu_to_be32(P2POUI);
@ -200,10 +178,8 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
u8 p2pie[8] = { 0x00 };
u32 p2pielen = 0;
DBG_88E("[%s]\n", __func__);
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
if (!pmgntframe)
return;
/* update attribute */
@ -215,7 +191,7 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
fctrl = &(pwlanhdr->frame_ctl);
fctrl = &pwlanhdr->frame_ctl;
*(fctrl) = 0;
memcpy(pwlanhdr->addr1, da, ETH_ALEN);
@ -230,11 +206,11 @@ static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 s
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
/* Build P2P public action frame header */
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
/* Build P2P IE */
/* P2P OUI */
@ -269,11 +245,11 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
unsigned char *pframe;
struct rtw_ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
if (!pmgntframe)
return;
/* update attribute */
@ -285,12 +261,12 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
fctrl = &(pwlanhdr->frame_ctl);
fctrl = &pwlanhdr->frame_ctl;
*(fctrl) = 0;
memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
@ -299,11 +275,11 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
wpsielen = 0;
/* WPS OUI */
@ -328,8 +304,6 @@ static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr,
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe(padapter, pmgntframe);
return;
}
static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
@ -340,8 +314,8 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
struct rtw_ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct adapter *padapter = pwdinfo->padapter;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
__be32 p2poui = cpu_to_be32(P2POUI);
u8 oui_subtype = P2P_PRESENCE_RESPONSE;
@ -349,10 +323,8 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
u8 noa_attr_content[32] = { 0x00 };
u32 p2pielen = 0;
DBG_88E("[%s]\n", __func__);
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
if (!pmgntframe)
return;
/* update attribute */
@ -364,7 +336,7 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
fctrl = &(pwlanhdr->frame_ctl);
fctrl = &pwlanhdr->frame_ctl;
*(fctrl) = 0;
memcpy(pwlanhdr->addr1, da, ETH_ALEN);
@ -379,10 +351,10 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
/* Build P2P action frame header */
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
/* Add P2P IE header */
/* P2P OUI */
@ -403,7 +375,7 @@ static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8
p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen));
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
pattrib->last_txcmdsz = pattrib->pktlen;
@ -437,10 +409,10 @@ u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
/* Be able to participate in additional P2P Groups and */
/* support the P2P Invitation Procedure */
/* Group Capability Bitmap, 1 byte */
capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY;
capability = P2P_DEVCAP_INVITATION_PROC | P2P_DEVCAP_CLIENT_DISCOVERABILITY;
capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
capability |= (P2P_GRPCAP_GROUP_FORMATION<<8);
capability |= (P2P_GRPCAP_GROUP_FORMATION << 8);
le_tmp = cpu_to_le16(capability);
p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp);
@ -753,13 +725,6 @@ u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status
return len;
}
u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
{
u32 len = 0;
return len;
}
u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
{
u8 *p;
@ -806,15 +771,15 @@ u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint l
ssid_len &= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen);
p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen);
if (p2pie) {
if ((p != NULL) && !memcmp((void *)(p+2), (void *)pwdinfo->p2p_wildcard_ssid , 7)) {
if (p && !memcmp((void *)(p + 2), (void *)pwdinfo->p2p_wildcard_ssid, 7)) {
/* todo: */
/* Check Requested Device Type attributes in WSC IE. */
/* Check Device ID attribute in P2P IE */
ret = true;
} else if ((p != NULL) && (ssid_len == 0)) {
} else if (p && ssid_len == 0) {
ret = true;
}
} else {
@ -851,35 +816,29 @@ u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint l
ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
if (!p2p_ie) {
DBG_88E("[%s] P2P IE not Found!!\n", __func__);
if (!p2p_ie)
status_code = P2P_STATUS_FAIL_INVALID_PARAM;
} else {
DBG_88E("[%s] P2P IE Found!!\n", __func__);
}
while (p2p_ie) {
/* Check P2P Capability ATTR */
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) {
DBG_88E("[%s] Got P2P Capability Attr!!\n", __func__);
cap_attr = le16_to_cpu(le_tmp);
psta->dev_cap = cap_attr&0xff;
psta->dev_cap = cap_attr & 0xff;
}
/* Check Extended Listen Timing ATTR */
/* Check P2P Device Info ATTR */
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) {
DBG_88E("[%s] Got P2P DEVICE INFO Attr!!\n", __func__);
pattr_content = rtw_zmalloc(attr_contentlen);
pattr_content = kzalloc(attr_contentlen, GFP_KERNEL);
pbuf = pattr_content;
if (pattr_content) {
u8 num_of_secdev_type;
u16 dev_name_len;
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint *)&attr_contentlen);
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint *)&attr_contentlen);
memcpy(psta->dev_addr, pattr_content, ETH_ALEN);/* P2P Device Address */
@ -904,28 +863,28 @@ u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint l
psta->num_of_secdev_type = num_of_secdev_type;
len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type*8)) ?
(sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8);
len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type * 8)) ?
(sizeof(psta->secdev_types_list)) : (num_of_secdev_type * 8);
memcpy(psta->secdev_types_list, pattr_content, len);
pattr_content += (num_of_secdev_type*8);
pattr_content += (num_of_secdev_type * 8);
}
psta->dev_name_len = 0;
if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(__be16 *)pattr_content)) {
dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content+2));
dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content + 2));
psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len;
memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len);
memcpy(psta->dev_name, pattr_content + 4, psta->dev_name_len);
}
kfree(pbuf);
}
}
/* Get the next P2P IE */
p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
}
return status_code;
@ -954,7 +913,7 @@ u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint le
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
!memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len)) {
!memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN, pwdinfo->p2p_group_ssid_len)) {
attr_contentlen = 0;
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) {
struct list_head *phead, *plist;
@ -969,7 +928,7 @@ u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint le
plist = plist->next;
if (psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
if (psta->is_p2p_device && (psta->dev_cap & P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
!memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) {
/* issue GO Discoverability Request */
issue_group_disc_req(pwdinfo, psta->hwaddr);
@ -1031,7 +990,6 @@ u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint l
issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
}
}
DBG_88E("[%s] config method = %s\n", __func__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
return true;
}
@ -1056,7 +1014,7 @@ static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_conte
peer_ch_list[j] = *(ch_content + 1 + i);
ch_content += (temp + 1);
ch_cnt -= (temp + 1);
ch_no += temp ;
ch_no += temp;
}
return ch_no;
@ -1110,7 +1068,6 @@ u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe,
memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
}
} else {
DBG_88E("[%s] WPS IE not Found!!\n", __func__);
result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
return result;
@ -1128,7 +1085,6 @@ u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe,
p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
if (!p2p_ie) {
DBG_88E("[%s] P2P IE not Found!!\n", __func__);
result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
}
@ -1145,8 +1101,7 @@ u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe,
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen)) {
DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
@ -1184,7 +1139,6 @@ u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe,
ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
if (ch_num_inclusioned == 0) {
DBG_88E("[%s] No common channel in channel list!\n", __func__);
result = P2P_STATUS_FAIL_NO_COMMON_CH;
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
break;
@ -1200,23 +1154,21 @@ u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe,
peer_operating_ch = operatingch_info[4];
if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
ch_list_inclusioned, ch_num_inclusioned)) {
ch_list_inclusioned,
ch_num_inclusioned))
/**
* Change our operating channel as peer's for compatibility.
*/
pwdinfo->operating_channel = peer_operating_ch;
DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
} else {
else
/* Take first channel of ch_list_inclusioned as operating channel */
pwdinfo->operating_channel = ch_list_inclusioned[0];
DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
}
}
}
}
/* Get the next P2P IE */
p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
}
return result;
}
@ -1235,9 +1187,7 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
/* Be able to know which one is the P2P GO and which one is P2P client. */
if (rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) {
} else {
DBG_88E("[%s] WPS IE not Found!!\n", __func__);
if (!rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) {
result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
}
@ -1260,7 +1210,6 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
while (p2p_ie) { /* Found the P2P IE. */
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
if (attr_contentlen == 1) {
DBG_88E("[%s] Status = %d\n", __func__, attr_content);
if (attr_content == P2P_STATUS_SUCCESS) {
/* Do nothing. */
} else {
@ -1285,8 +1234,7 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
/* Try to get the peer's intent and tie breaker value. */
attr_content = 0x00;
attr_contentlen = 0;
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen)) {
DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
@ -1323,20 +1271,20 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
/* Try to get the operation channel information */
attr_contentlen = 0;
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
if (rtw_get_p2p_attr_content(p2p_ie,
p2p_ielen,
P2P_ATTR_OPERATING_CH,
operatingch_info,
&attr_contentlen))
pwdinfo->peer_operating_ch = operatingch_info[4];
}
/* Try to get the channel list information */
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) {
DBG_88E("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len);
peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
if (ch_num_inclusioned == 0) {
DBG_88E("[%s] No common channel in channel list!\n", __func__);
result = P2P_STATUS_FAIL_NO_COMMON_CH;
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
break;
@ -1352,21 +1300,16 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
peer_operating_ch = operatingch_info[4];
if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
ch_list_inclusioned, ch_num_inclusioned)) {
ch_list_inclusioned, ch_num_inclusioned))
/**
* Change our operating channel as peer's for compatibility.
*/
pwdinfo->operating_channel = peer_operating_ch;
DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
} else {
else
/* Take first channel of ch_list_inclusioned as operating channel */
pwdinfo->operating_channel = ch_list_inclusioned[0];
DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
}
}
}
} else {
DBG_88E("[%s] channel list attribute not found!\n", __func__);
}
/* Try to get the group id information if peer is GO */
@ -1378,7 +1321,7 @@ u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe
}
/* Get the next P2P IE */
p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
}
}
return result;
@ -1403,13 +1346,10 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr
pwdinfo->negotiation_dialog_token = 1;
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
if (attr_contentlen == 1) {
DBG_88E("[%s] Status = %d\n", __func__, attr_content);
result = attr_content;
if (attr_content == P2P_STATUS_SUCCESS) {
u8 bcancelled = 0;
_cancel_timer(&pwdinfo->restore_p2p_state_timer, &bcancelled);
del_timer_sync(&pwdinfo->restore_p2p_state_timer);
/* Commented by Albert 20100911 */
/* Todo: Need to handle the case which both Intents are the same. */
@ -1437,19 +1377,20 @@ u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pfr
attr_contentlen = 0;
memset(groupid, 0x00, 38);
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
DBG_88E("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]));
memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
}
attr_contentlen = 0;
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
if (rtw_get_p2p_attr_content(p2p_ie,
p2p_ielen,
P2P_ATTR_OPERATING_CH,
operatingch_info,
&attr_contentlen))
pwdinfo->peer_operating_ch = operatingch_info[4];
}
/* Get the next P2P IE */
p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
}
return result;
}
@ -1512,7 +1453,7 @@ static void pre_tx_invitereq_handler(struct adapter *padapter)
u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@ -1524,7 +1465,7 @@ static void pre_tx_provdisc_handler(struct adapter *padapter)
u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@ -1536,7 +1477,7 @@ static void pre_tx_negoreq_handler(struct adapter *padapter)
u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@ -1574,7 +1515,7 @@ void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */
u32 attr_contentlen = 0;
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
u8 find_p2p = false, find_p2p_ps = false;
u8 noa_offset, noa_num, noa_index;
@ -1641,7 +1582,7 @@ void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
}
/* Get the next P2P IE */
p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
}
if (find_p2p) {
@ -1654,14 +1595,14 @@ void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
/* Pre action for p2p state */
switch (p2p_ps_state) {
case P2P_PS_DISABLE:
pwdinfo->p2p_ps_state = p2p_ps_state;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
pwdinfo->noa_index = 0;
pwdinfo->ctwindow = 0;
@ -1671,7 +1612,7 @@ void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
if (padapter->pwrctrlpriv.bFwCurrentInPSMode) {
if (pwrpriv->smart_ps == 0) {
pwrpriv->smart_ps = 2;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode));
}
}
break;
@ -1682,11 +1623,10 @@ void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
if (pwdinfo->ctwindow > 0) {
if (pwrpriv->smart_ps != 0) {
pwrpriv->smart_ps = 0;
DBG_88E("%s(): Enter CTW, change SmartPS\n", __func__);
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode));
}
}
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
}
break;
case P2P_PS_SCAN:
@ -1694,7 +1634,7 @@ void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
case P2P_PS_ALLSTASLEEP:
if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
pwdinfo->p2p_ps_state = p2p_ps_state;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
}
break;
default:
@ -1707,7 +1647,7 @@ u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
{
struct cmd_obj *ph2c;
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
@ -1715,14 +1655,14 @@ u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
return res;
if (enqueue) {
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
if (ph2c == NULL) {
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!ph2c) {
res = _FAIL;
goto exit;
}
pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
if (pdrvextra_cmd_parm == NULL) {
pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
if (!pdrvextra_cmd_parm) {
kfree(ph2c);
res = _FAIL;
goto exit;
@ -1744,61 +1684,35 @@ exit:
return res;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
static void reset_ch_sitesurvey_timer_process(struct timer_list *t)
#else
static void reset_ch_sitesurvey_timer_process (void *FunctionContext)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
#else
struct adapter *adapter = (struct adapter *)FunctionContext;
#endif
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
return;
DBG_88E("[%s] In\n", __func__);
/* Reset the operation channel information */
pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
static void reset_ch_sitesurvey_timer_process2 (struct timer_list *t)
#else
static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext)
#endif
static void reset_ch_sitesurvey_timer_process2(struct timer_list *t)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
#else
struct adapter *adapter = (struct adapter *)FunctionContext;
#endif
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
return;
DBG_88E("[%s] In\n", __func__);
/* Reset the operation channel information */
pwdinfo->p2p_info.operation_ch[0] = 0;
pwdinfo->p2p_info.scan_op_ch_only = 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
static void restore_p2p_state_timer_process(struct timer_list *t)
#else
static void restore_p2p_state_timer_process (void *FunctionContext)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct adapter *adapter = from_timer(adapter, t, wdinfo.restore_p2p_state_timer);
#else
struct adapter *adapter = (struct adapter *)FunctionContext;
#endif
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
@ -1807,17 +1721,9 @@ static void restore_p2p_state_timer_process (void *FunctionContext)
p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
static void pre_tx_scan_timer_process(struct timer_list *t)
#else
static void pre_tx_scan_timer_process(void *FunctionContext)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct adapter *adapter = from_timer(adapter, t, wdinfo.pre_tx_scan_timer);
#else
struct adapter *adapter = (struct adapter *)FunctionContext;
#endif
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
@ -1838,24 +1744,14 @@ static void pre_tx_scan_timer_process(void *FunctionContext)
} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
if (pwdinfo->invitereq_info.benable)
p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK);
} else {
DBG_88E("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo));
}
spin_unlock_bh(&pmlmepriv->lock);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
static void find_phase_timer_process(struct timer_list *t)
#else
static void find_phase_timer_process(void *FunctionContext)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct adapter *adapter = from_timer(adapter, t, wdinfo.find_phase_timer);
#else
struct adapter *adapter = (struct adapter *)FunctionContext;
#endif
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
@ -1873,32 +1769,21 @@ void reset_global_wifidirect_info(struct adapter *padapter)
pwdinfo = &padapter->wdinfo;
pwdinfo->persistent_supported = 0;
pwdinfo->session_available = true;
pwdinfo->wfd_tdls_enable = 0;
pwdinfo->wfd_tdls_weaksec = 0;
}
void rtw_init_wifidirect_timers(struct adapter *padapter)
{
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&pwdinfo->find_phase_timer, find_phase_timer_process, 0);
timer_setup(&pwdinfo->restore_p2p_state_timer, restore_p2p_state_timer_process, 0);
timer_setup(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process, 0);
timer_setup(&pwdinfo->reset_ch_sitesurvey, reset_ch_sitesurvey_timer_process, 0);
timer_setup(&pwdinfo->reset_ch_sitesurvey2, reset_ch_sitesurvey_timer_process2, 0);
#else
_init_timer(&pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter);
_init_timer(&pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter);
_init_timer(&pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter);
_init_timer(&pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter);
_init_timer(&pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter);
#endif
}
void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr)
{
#ifdef CONFIG_88EU_P2P
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
/*init device&interface address */
@ -1906,7 +1791,6 @@ void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface
memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
if (iface_addr)
memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
#endif
}
void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
@ -1968,7 +1852,7 @@ void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
pwdinfo->listen_dwell = (u8) ((jiffies % 3) + 1);
pwdinfo->listen_dwell = (u8)((jiffies % 3) + 1);
memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info));
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
@ -1989,7 +1873,6 @@ void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4);
memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3);
memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
pwdinfo->wfd_tdls_enable = 0;
memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN);
@ -2004,7 +1887,7 @@ void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
{
int ret = _SUCCESS;
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) {
/* leave IPS/Autosuspend */
@ -2016,12 +1899,11 @@ int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
/* Added by Albert 2011/03/22 */
/* In the P2P mode, the driver should not support the b mode. */
/* So, the Tx packet shouldn't use the CCK rate */
update_tx_basic_rate(padapter, WIRELESS_11AGN);
update_tx_basic_rate(padapter, (WIRELESS_11G | WIRELESS_11_24N));
/* Enable P2P function */
init_wifidirect_info(padapter, role);
rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, true);
} else if (role == P2P_ROLE_DISABLE) {
if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = _FAIL;
@ -2035,18 +1917,11 @@ int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
_cancel_timer_ex(&pwdinfo->pre_tx_scan_timer);
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey2);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
#else
reset_ch_sitesurvey_timer_process(padapter);
reset_ch_sitesurvey_timer_process2(padapter);
#endif
rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
}
rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, false);
/* Restore to initial setting. */
update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
}
@ -2054,15 +1929,3 @@ int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
exit:
return ret;
}
#else
u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
{
return _FAIL;
}
void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
{
}
#endif /* CONFIG_88EU_P2P */

View file

@ -1,46 +1,24 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2012 Realtek Corporation. */
#define _RTW_PWRCTRL_C_
#include <osdep_service.h>
#include <drv_types.h>
#include <osdep_intf.h>
#include <linux/usb.h>
#include "../include/osdep_service.h"
#include "../include/drv_types.h"
#include "../include/osdep_intf.h"
#include "../include/linux/usb.h"
#include <linux/version.h>
void ips_enter(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct xmit_priv *pxmit_priv = &padapter->xmitpriv;
if (padapter->registrypriv.mp_mode == 1)
return;
if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
DBG_88E_LEVEL(_drv_info_, "There are some pkts to transmit\n");
DBG_88E_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n",
pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt);
pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF)
return;
}
_enter_pwrlock(&pwrpriv->lock);
mutex_lock(&pwrpriv->lock);
pwrpriv->bips_processing = true;
@ -48,10 +26,8 @@ void ips_enter(struct adapter *padapter)
pwrpriv->ips_mode = pwrpriv->ips_mode_req;
pwrpriv->ips_enter_cnts++;
DBG_88E("==>ips_enter cnts:%d\n", pwrpriv->ips_enter_cnts);
if (rf_off == pwrpriv->change_rfpwrstate) {
pwrpriv->bpower_saving = true;
DBG_88E_LEVEL(_drv_info_, "nolinked power save enter\n");
if (pwrpriv->ips_mode == IPS_LEVEL_2)
pwrpriv->bkeepfwalive = true;
@ -61,33 +37,30 @@ void ips_enter(struct adapter *padapter)
}
pwrpriv->bips_processing = false;
_exit_pwrlock(&pwrpriv->lock);
mutex_unlock(&pwrpriv->lock);
}
int ips_leave(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct security_priv *psecuritypriv = &(padapter->securitypriv);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int result = _SUCCESS;
int keyid;
_enter_pwrlock(&pwrpriv->lock);
mutex_lock(&pwrpriv->lock);
if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
pwrpriv->bips_processing = true;
pwrpriv->change_rfpwrstate = rf_on;
pwrpriv->ips_leave_cnts++;
DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
result = rtw_ips_pwr_up(padapter);
if (result == _SUCCESS) {
pwrpriv->rf_pwrstate = rf_on;
}
DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n");
if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) {
DBG_88E("==>%s, channel(%d), processing(%x)\n", __func__, padapter->mlmeextpriv.cur_channel, pwrpriv->bips_processing);
set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
for (keyid = 0; keyid < 4; keyid++) {
if (pmlmepriv->key_mask & BIT(keyid)) {
@ -99,14 +72,13 @@ int ips_leave(struct adapter *padapter)
}
}
DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
pwrpriv->bips_processing = false;
pwrpriv->bkeepfwalive = false;
pwrpriv->bpower_saving = false;
}
_exit_pwrlock(&pwrpriv->lock);
mutex_unlock(&pwrpriv->lock);
return result;
}
@ -114,44 +86,31 @@ int ips_leave(struct adapter *padapter)
static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
{
struct adapter *buddy = adapter->pbuddy_adapter;
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
#ifdef CONFIG_88EU_P2P
struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
#endif
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
bool ret = false;
if (adapter->pwrctrlpriv.ips_deny_time >= jiffies)
goto exit;
if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
check_fwstate(pmlmepriv, WIFI_UNDER_WPS) ||
check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) ||
#if defined(CONFIG_88EU_P2P)
check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
#else
0)
#endif
goto exit;
/* consider buddy, if exist */
if (buddy) {
struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv);
#ifdef CONFIG_88EU_P2P
struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo);
#endif
struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
struct wifidirect_info *b_pwdinfo = &buddy->wdinfo;
if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE | WIFI_SITE_MONITOR) ||
check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS) ||
check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) ||
#if defined(CONFIG_88EU_P2P)
check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) ||
!rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE))
#else
0)
#endif
goto exit;
}
ret = true;
@ -163,41 +122,19 @@ exit:
void rtw_ps_processor(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
enum rt_rf_power_state rfpwrstate;
pwrpriv->ps_processing = true;
if (pwrpriv->bips_processing)
goto exit;
if (padapter->pwrctrlpriv.bHWPwrPindetect) {
rfpwrstate = RfOnOffDetect(padapter);
DBG_88E("@@@@- #2 %s==> rfstate:%s\n", __func__, (rfpwrstate == rf_on) ? "rf_on" : "rf_off");
if (rfpwrstate != pwrpriv->rf_pwrstate) {
if (rfpwrstate == rf_off) {
pwrpriv->change_rfpwrstate = rf_off;
pwrpriv->brfoffbyhw = true;
padapter->bCardDisableWOHSM = true;
rtw_hw_suspend(padapter);
} else {
pwrpriv->change_rfpwrstate = rf_on;
rtw_hw_resume(padapter);
}
DBG_88E("current rf_pwrstate(%s)\n", (pwrpriv->rf_pwrstate == rf_off) ? "rf_off" : "rf_on");
}
pwrpriv->pwr_state_check_cnts++;
}
if (pwrpriv->ips_mode_req == IPS_NONE)
goto exit;
if (!rtw_pwr_unassociated_idle(padapter))
goto exit;
if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4) == 0)) {
DBG_88E("==>%s .fw_state(%x)\n", __func__, get_fwstate(pmlmepriv));
if ((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts % 4) == 0)) {
pwrpriv->change_rfpwrstate = rf_off;
ips_enter(padapter);
@ -205,7 +142,6 @@ void rtw_ps_processor(struct adapter *padapter)
exit:
rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
pwrpriv->ps_processing = false;
return;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
@ -224,71 +160,11 @@ static void pwr_state_check_handler(void *FunctionContext)
rtw_ps_cmd(padapter);
}
/*
*
* Parameters
* padapter
* pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
*
*/
void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
{
u8 rpwm;
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
pslv = PS_STATE(pslv);
if (pwrpriv->btcoex_rfon) {
if (pslv < PS_STATE_S4)
pslv = PS_STATE_S3;
}
if ((pwrpriv->rpwm == pslv)) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
return;
}
if ((padapter->bSurpriseRemoved) ||
(!padapter->hw_init_completed)) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
("%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
__func__, padapter->bSurpriseRemoved, padapter->hw_init_completed));
pwrpriv->cpwm = PS_STATE_S4;
return;
}
if (padapter->bDriverStopped) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
("%s: change power state(0x%02X) when DriverStopped\n", __func__, pslv));
if (pslv < PS_STATE_S2) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __func__, pslv));
return;
}
}
rpwm = pslv | pwrpriv->tog;
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm));
pwrpriv->rpwm = pslv;
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
pwrpriv->tog += 0x80;
pwrpriv->cpwm = pslv;
}
static u8 PS_RDY_CHECK(struct adapter *padapter)
static bool PS_RDY_CHECK(struct adapter *padapter)
{
u32 curr_time, delta_time;
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
curr_time = jiffies;
delta_time = curr_time - pwrpriv->DelayLPSLastTimeStamp;
@ -296,36 +172,27 @@ static u8 PS_RDY_CHECK(struct adapter *padapter)
if (delta_time < LPS_DELAY_TIME)
return false;
if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) ||
(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ||
(check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
if (!check_fwstate(pmlmepriv, _FW_LINKED) ||
check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) ||
check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
return false;
if (pwrpriv->bInSuspend)
return false;
if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) {
DBG_88E("Group handshake still in progress !!!\n");
if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
!padapter->securitypriv.binstallGrpkey)
return false;
}
return true;
}
void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
#ifdef CONFIG_88EU_P2P
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
#endif /* CONFIG_88EU_P2P */
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
("%s: PowerMode=%d Smart_PS=%d\n",
__func__, ps_mode, smart_ps));
if (ps_mode > PM_Card_Disable) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, ("ps_mode:%d error\n", ps_mode));
if (ps_mode > PM_Card_Disable)
return;
}
if (pwrpriv->pwr_mode == ps_mode) {
if (PS_MODE_ACTIVE == ps_mode)
@ -338,31 +205,22 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a
/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
if (ps_mode == PS_MODE_ACTIVE) {
#ifdef CONFIG_88EU_P2P
if (pwdinfo->opp_ps == 0) {
DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n");
pwrpriv->pwr_mode = ps_mode;
rtw_set_rpwm(padapter, PS_STATE_S4);
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
pwrpriv->bFwCurrentInPSMode = false;
}
} else {
#endif /* CONFIG_88EU_P2P */
if (PS_RDY_CHECK(padapter)) {
DBG_88E("%s: Enter 802.11 power save\n", __func__);
pwrpriv->bFwCurrentInPSMode = true;
pwrpriv->pwr_mode = ps_mode;
pwrpriv->smart_ps = smart_ps;
pwrpriv->bcn_ant_mode = bcn_ant_mode;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
#ifdef CONFIG_88EU_P2P
/* Set CTWindow after LPS */
if (pwdinfo->opp_ps == 1)
p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
#endif /* CONFIG_88EU_P2P */
rtw_set_rpwm(padapter, PS_STATE_S2);
}
}
@ -382,19 +240,17 @@ s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
start_time = jiffies;
while (1) {
rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake);
GetHwReg8188EU(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 (rtw_get_passing_time_ms(start_time) > delay_ms) {
err = -1;
DBG_88E("%s: Wait for FW LPS leave more than %u ms!!!\n", __func__, delay_ms);
break;
}
rtw_usleep_os(100);
@ -411,7 +267,7 @@ void LPS_Enter(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
if (PS_RDY_CHECK(padapter) == false)
if (!PS_RDY_CHECK(padapter))
return;
if (pwrpriv->bLeisurePs) {
@ -419,7 +275,6 @@ void LPS_Enter(struct adapter *padapter)
if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
pwrpriv->bpower_saving = true;
DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps);
/* For Tenda W311R IOT issue */
rtw_set_ps_mode(padapter, pwrpriv->power_mgnt,
pwrpriv->smart_ps, 0x40);
@ -458,7 +313,7 @@ void LPS_Leave(struct adapter *padapter)
/* */
void LeaveAllPowerSaveMode(struct adapter *Adapter)
{
struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
u8 enqueue = 0;
if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
@ -473,7 +328,7 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter)
{
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
_init_pwrlock(&pwrctrlpriv->lock);
mutex_init(&pwrctrlpriv->lock);
pwrctrlpriv->rf_pwrstate = rf_on;
pwrctrlpriv->ips_enter_cnts = 0;
pwrctrlpriv->ips_leave_cnts = 0;
@ -484,59 +339,27 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter)
pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
pwrctrlpriv->pwr_state_check_cnts = 0;
pwrctrlpriv->bInternalAutoSuspend = false;
pwrctrlpriv->bInSuspend = false;
pwrctrlpriv->bkeepfwalive = false;
pwrctrlpriv->LpsIdleCount = 0;
if (padapter->registrypriv.mp_mode == 1)
pwrctrlpriv->power_mgnt = PS_MODE_ACTIVE ;
else
pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */
pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */
pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ? true : false;
pwrctrlpriv->bFwCurrentInPSMode = false;
pwrctrlpriv->rpwm = 0;
pwrctrlpriv->cpwm = PS_STATE_S4;
pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
pwrctrlpriv->bcn_ant_mode = 0;
pwrctrlpriv->tog = 0x80;
pwrctrlpriv->btcoex_rfon = false;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0);
#else
_init_timer(&(pwrctrlpriv->pwr_state_check_timer), padapter->pnetdev, pwr_state_check_handler, (u8 *)padapter);
_init_timer(&(pwrctrlpriv->pwr_state_check_timer), padapter->pnetdev,
pwr_state_check_handler, (u8 *)padapter);
#endif
}
void rtw_free_pwrctrl_priv(struct adapter *adapter)
{
struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
_free_pwrlock(&pwrctrlpriv->lock);
}
u8 rtw_interface_ps_func(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val)
{
u8 bResult = true;
rtw_hal_intf_ps_func(padapter, efunc_id, val);
return bResult;
}
inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms);
}
/*
* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
* @adapter: pointer to struct adapter structure
@ -555,31 +378,16 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
if (pwrpriv->ps_processing) {
DBG_88E("%s wait ps_processing...\n", __func__);
while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000)
rtw_msleep_os(10);
if (pwrpriv->ps_processing)
DBG_88E("%s wait ps_processing timeout\n", __func__);
else
DBG_88E("%s wait ps_processing done\n", __func__);
msleep(10);
}
/* System suspend is not allowed to wakeup */
if ((!pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) {
if (pwrpriv->bInSuspend) {
while (pwrpriv->bInSuspend &&
(rtw_get_passing_time_ms(start) <= 3000 ||
(rtw_get_passing_time_ms(start) <= 500)))
rtw_msleep_os(10);
if (pwrpriv->bInSuspend)
DBG_88E("%s wait bInSuspend timeout\n", __func__);
else
DBG_88E("%s wait bInSuspend done\n", __func__);
}
/* block??? */
if ((pwrpriv->bInternalAutoSuspend) && (padapter->net_closed)) {
ret = _FAIL;
goto exit;
msleep(10);
}
/* I think this should be check in IPS, LPS, autosuspend functions... */
@ -588,9 +396,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
goto exit;
}
if (rf_off == pwrpriv->rf_pwrstate) {
DBG_88E("%s call ips_leave....\n", __func__);
if (_FAIL == ips_leave(padapter)) {
DBG_88E("======> ips_leave fail.............\n");
ret = _FAIL;
goto exit;
}
@ -599,11 +405,6 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
/* TODO: the following checking need to be merged... */
if (padapter->bDriverStopped || !padapter->bup ||
!padapter->hw_init_completed) {
DBG_88E("%s: bDriverStopped=%d, bup=%d, hw_init_completed =%u\n"
, caller
, padapter->bDriverStopped
, padapter->bup
, padapter->hw_init_completed);
ret = false;
goto exit;
}
@ -641,11 +442,9 @@ int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
rtw_ips_mode_req(pwrctrlpriv, mode);
DBG_88E("%s %s\n", __func__, mode == IPS_NORMAL ? "IPS_NORMAL" : "IPS_LEVEL_2");
return 0;
} else if (mode == IPS_NONE) {
rtw_ips_mode_req(pwrctrlpriv, mode);
DBG_88E("%s %s\n", __func__, "IPS_NONE");
if ((padapter->bSurpriseRemoved == 0) && (_FAIL == rtw_pwr_wakeup(padapter)))
return -EFAULT;
} else {

File diff suppressed because it is too large Load diff

View file

@ -1,88 +1,29 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_RF_C_
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <xmit_osdep.h>
#include "../include/drv_types.h"
struct ch_freq {
u32 channel;
u32 frequency;
static const u32 ch_freq_map[] = {
2412,
2417,
2422,
2427,
2432,
2437,
2442,
2447,
2452,
2457,
2462,
2467,
2472,
2484
};
static struct ch_freq ch_freq_map[] = {
{1, 2412}, {2, 2417}, {3, 2422}, {4, 2427}, {5, 2432},
{6, 2437}, {7, 2442}, {8, 2447}, {9, 2452}, {10, 2457},
{11, 2462}, {12, 2467}, {13, 2472}, {14, 2484},
/* UNII */
{36, 5180}, {40, 5200}, {44, 5220}, {48, 5240}, {52, 5260},
{56, 5280}, {60, 5300}, {64, 5320}, {149, 5745}, {153, 5765},
{157, 5785}, {161, 5805}, {165, 5825}, {167, 5835}, {169, 5845},
{171, 5855}, {173, 5865},
/* HiperLAN2 */
{100, 5500}, {104, 5520}, {108, 5540}, {112, 5560}, {116, 5580},
{120, 5600}, {124, 5620}, {128, 5640}, {132, 5660}, {136, 5680},
{140, 5700},
/* Japan MMAC */
{34, 5170}, {38, 5190}, {42, 5210}, {46, 5230},
/* Japan */
{184, 4920}, {188, 4940}, {192, 4960}, {196, 4980},
{208, 5040},/* Japan, means J08 */
{212, 5060},/* Japan, means J12 */
{216, 5080},/* Japan, means J16 */
};
static int ch_freq_map_num = (sizeof(ch_freq_map) / sizeof(struct ch_freq));
u32 rtw_ch2freq(u32 channel)
{
u8 i;
u32 freq = 0;
if (channel == 0 || channel > ARRAY_SIZE(ch_freq_map))
return 2412;
for (i = 0; i < ch_freq_map_num; i++) {
if (channel == ch_freq_map[i].channel) {
freq = ch_freq_map[i].frequency;
break;
}
}
if (i == ch_freq_map_num)
freq = 2412;
return freq;
}
u32 rtw_freq2ch(u32 freq)
{
u8 i;
u32 ch = 0;
for (i = 0; i < ch_freq_map_num; i++) {
if (freq == ch_freq_map[i].frequency) {
ch = ch_freq_map[i].channel;
break;
}
}
if (i == ch_freq_map_num)
ch = 1;
return ch;
return ch_freq_map[channel - 1];
}

File diff suppressed because it is too large Load diff

View file

@ -1,79 +0,0 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#include <rtw_sreset.h>
void sreset_init_value(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
_rtw_mutex_init(&psrtpriv->silentreset_mutex);
psrtpriv->silent_reset_inprogress = false;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
}
void sreset_reset_value(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
psrtpriv->silent_reset_inprogress = false;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
}
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;
if (psrtpriv->silent_reset_inprogress)
return status;
val32 = rtw_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;
}
void sreset_set_wifi_error_status(struct adapter *padapter, u32 status)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.Wifi_Error_Status = status;
}

View file

@ -1,47 +1,29 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2011 Realtek Corporation. */
#define _RTW_STA_MGT_C_
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <xmit_osdep.h>
#include <mlme_osdep.h>
#include <sta_info.h>
#include "../include/osdep_service.h"
#include "../include/drv_types.h"
#include "../include/recv_osdep.h"
#include "../include/xmit_osdep.h"
#include "../include/mlme_osdep.h"
#include "../include/sta_info.h"
static void _rtw_init_stainfo(struct sta_info *psta)
{
memset((u8 *)psta, 0, sizeof (struct sta_info));
memset((u8 *)psta, 0, sizeof(struct sta_info));
spin_lock_init(&psta->lock);
spin_lock_init(&psta->lock);
INIT_LIST_HEAD(&psta->list);
INIT_LIST_HEAD(&psta->hash_list);
_rtw_init_queue(&psta->sleep_q);
rtw_init_queue(&psta->sleep_q);
psta->sleepq_len = 0;
_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
_rtw_init_sta_recv_priv(&psta->sta_recvpriv);
#ifdef CONFIG_88EU_AP_MODE
INIT_LIST_HEAD(&psta->asoc_list);
INIT_LIST_HEAD(&psta->auth_list);
@ -54,21 +36,16 @@ static void _rtw_init_stainfo(struct sta_info *psta)
psta->bpairwise_key_installed = false;
#ifdef CONFIG_88EU_AP_MODE
psta->nonerp_set = 0;
psta->no_short_slot_time_set = 0;
psta->no_short_preamble_set = 0;
psta->no_ht_gf_set = 0;
psta->no_ht_set = 0;
psta->ht_20mhz_set = 0;
#endif
psta->under_exist_checking = 0;
psta->keep_alive_trycnt = 0;
#endif /* CONFIG_88EU_AP_MODE */
}
u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
@ -76,7 +53,7 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
struct sta_info *psta;
s32 i;
pstapriv->pallocated_stainfo_buf = rtw_zvmalloc(sizeof(struct sta_info) * NUM_STA + 4);
pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
if (!pstapriv->pallocated_stainfo_buf)
return _FAIL;
@ -84,28 +61,26 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
_rtw_init_queue(&pstapriv->free_sta_queue);
rtw_init_queue(&pstapriv->free_sta_queue);
spin_lock_init(&pstapriv->sta_hash_lock);
pstapriv->asoc_sta_count = 0;
_rtw_init_queue(&pstapriv->sleep_q);
_rtw_init_queue(&pstapriv->wakeup_q);
rtw_init_queue(&pstapriv->sleep_q);
rtw_init_queue(&pstapriv->wakeup_q);
psta = (struct sta_info *)(pstapriv->pstainfo_buf);
for (i = 0; i < NUM_STA; i++) {
_rtw_init_stainfo(psta);
INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
psta++;
}
#ifdef CONFIG_88EU_AP_MODE
pstapriv->sta_dz_bitmap = 0;
pstapriv->tim_bitmap = 0;
@ -120,105 +95,21 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
pstapriv->assoc_to = 3;
pstapriv->expire_to = 3; /* 3*2 = 6 sec */
pstapriv->max_num_sta = NUM_STA;
#endif
return _SUCCESS;
}
inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
{
int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
if (!stainfo_offset_valid(offset))
DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
return offset;
return (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info);
}
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));
}
void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv);
void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv)
{
_rtw_spinlock_free(&psta_xmitpriv->lock);
_rtw_spinlock_free(&(psta_xmitpriv->be_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock));
}
static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv)
{
_rtw_spinlock_free(&psta_recvpriv->lock);
_rtw_spinlock_free(&(psta_recvpriv->defrag_q.lock));
}
void rtw_mfree_stainfo(struct sta_info *psta);
void rtw_mfree_stainfo(struct sta_info *psta)
{
if (&psta->lock != NULL)
_rtw_spinlock_free(&psta->lock);
_rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv);
_rtw_free_sta_recv_priv_lock(&psta->sta_recvpriv);
}
/* this function is used to free the memory of lock || sema for all stainfos */
void rtw_mfree_all_stainfo(struct sta_priv *pstapriv);
void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
{
struct list_head *plist, *phead;
struct sta_info *psta = NULL;
spin_lock_bh(&pstapriv->sta_hash_lock);
phead = get_list_head(&pstapriv->free_sta_queue);
plist = phead->next;
while (phead != plist) {
psta = container_of(plist, struct sta_info , list);
plist = plist->next;
}
spin_unlock_bh(&pstapriv->sta_hash_lock);
}
static void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
{
#ifdef CONFIG_88EU_AP_MODE
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
#endif
rtw_mfree_all_stainfo(pstapriv); /* be done before free sta_hash_lock */
_rtw_spinlock_free(&pstapriv->free_sta_queue.lock);
_rtw_spinlock_free(&pstapriv->sta_hash_lock);
_rtw_spinlock_free(&pstapriv->wakeup_q.lock);
_rtw_spinlock_free(&pstapriv->sleep_q.lock);
#ifdef CONFIG_88EU_AP_MODE
_rtw_spinlock_free(&pstapriv->asoc_list_lock);
_rtw_spinlock_free(&pstapriv->auth_list_lock);
_rtw_spinlock_free(&pacl_list->acl_node_q.lock);
#endif
}
u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
void _rtw_free_sta_priv(struct sta_priv *pstapriv)
{
struct list_head *phead, *plist;
struct sta_info *psta = NULL;
@ -229,12 +120,12 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
/* delete all reordering_ctrl_timer */
spin_lock_bh(&pstapriv->sta_hash_lock);
for (index = 0; index < NUM_STA; index++) {
phead = &(pstapriv->sta_hash[index]);
phead = &pstapriv->sta_hash[index];
plist = phead->next;
while (phead != plist) {
int i;
psta = container_of(plist, struct sta_info , hash_list);
psta = container_of(plist, struct sta_info, hash_list);
plist = plist->next;
for (i = 0; i < 16; i++) {
@ -246,13 +137,8 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
spin_unlock_bh(&pstapriv->sta_hash_lock);
/*===============================*/
rtw_mfree_sta_priv_lock(pstapriv);
if (pstapriv->pallocated_stainfo_buf)
rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
}
return _SUCCESS;
vfree(pstapriv->pallocated_stainfo_buf);
}
}
struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
@ -274,24 +160,22 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
psta = NULL;
} else {
psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
list_del_init(&(psta->list));
list_del_init(&psta->list);
spin_unlock_bh(&pfree_sta_queue->lock);
_rtw_init_stainfo(psta);
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
index = wifi_mac_hash(hwaddr);
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("rtw_alloc_stainfo: index=%x", index));
if (index >= NUM_STA) {
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => rtw_alloc_stainfo: index >= NUM_STA"));
psta = NULL;
goto exit;
}
phash_list = &(pstapriv->sta_hash[index]);
phash_list = &pstapriv->sta_hash[index];
spin_lock_bh(&pstapriv->sta_hash_lock);
list_add_tail(&psta->hash_list, phash_list);
pstapriv->asoc_sta_count++ ;
pstapriv->asoc_sta_count++;
spin_unlock_bh(&pstapriv->sta_hash_lock);
@ -303,10 +187,6 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
for (i = 0; i < 16; i++)
memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
("alloc number_%d stainfo with hwaddr = %pM\n",
pstapriv->asoc_sta_count , hwaddr));
init_addba_retry_timer(pstapriv->padapter, psta);
/* for A-MPDU Rx reordering buffer control */
@ -321,7 +201,7 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
preorder_ctrl->wend_b = 0xffff;
preorder_ctrl->wsize_b = 64;/* 64; */
_rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
rtw_init_recv_timer(preorder_ctrl);
}
@ -340,7 +220,7 @@ exit:
}
/* using pstapriv->sta_hash_lock to protect */
u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
{
int i;
struct __queue *pfree_sta_queue;
@ -349,7 +229,7 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct sta_priv *pstapriv = &padapter->stapriv;
if (psta == NULL)
if (!psta)
goto exit;
pfree_sta_queue = &pstapriv->free_sta_queue;
@ -363,24 +243,23 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
list_del_init(&pstaxmitpriv->vo_q.tx_pending);
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
list_del_init(&pstaxmitpriv->vi_q.tx_pending);
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
list_del_init(&pstaxmitpriv->bk_q.tx_pending);
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
list_del_init(&(pstaxmitpriv->be_q.tx_pending));
list_del_init(&pstaxmitpriv->be_q.tx_pending);
spin_unlock_bh(&pxmitpriv->lock);
list_del_init(&psta->hash_list);
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("\n free number_%d stainfo with hwaddr=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4], psta->hwaddr[5]));
pstapriv->asoc_sta_count--;
/* re-init sta_info; 20061114 */
@ -412,7 +291,7 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
plist = plist->next;
list_del_init(&(prframe->list));
list_del_init(&prframe->list);
rtw_free_recvframe(prframe, pfree_recv_queue);
}
@ -421,9 +300,7 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
}
if (!(psta->state & WIFI_AP_STATE))
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
#ifdef CONFIG_88EU_AP_MODE
rtl8188e_SetHalODMVar(padapter, psta, false);
spin_lock_bh(&pstapriv->auth_list_lock);
if (!list_empty(&psta->auth_list)) {
@ -454,8 +331,6 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
psta->under_exist_checking = 0;
#endif /* CONFIG_88EU_AP_MODE */
spin_lock_bh(&pfree_sta_queue->lock);
list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
spin_unlock_bh(&pfree_sta_queue->lock);
@ -480,16 +355,16 @@ void rtw_free_all_stainfo(struct adapter *padapter)
spin_lock_bh(&pstapriv->sta_hash_lock);
for (index = 0; index < NUM_STA; index++) {
phead = &(pstapriv->sta_hash[index]);
phead = &pstapriv->sta_hash[index];
plist = phead->next;
while (phead != plist) {
psta = container_of(plist, struct sta_info , hash_list);
psta = container_of(plist, struct sta_info, hash_list);
plist = plist->next;
if (pbcmc_stainfo != psta)
rtw_free_stainfo(padapter , psta);
rtw_free_stainfo(padapter, psta);
}
}
spin_unlock_bh(&pstapriv->sta_hash_lock);
@ -504,7 +379,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if (hwaddr == NULL)
if (!hwaddr)
return NULL;
if (IS_MCAST(hwaddr))
@ -516,7 +391,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
spin_lock_bh(&pstapriv->sta_hash_lock);
phead = &(pstapriv->sta_hash[index]);
phead = &pstapriv->sta_hash[index];
plist = phead->next;
while (phead != plist) {
@ -544,9 +419,8 @@ u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
if (psta == NULL) {
if (!psta) {
res = _FAIL;
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
goto exit;
}
@ -564,7 +438,7 @@ struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
struct sta_priv *pstapriv = &padapter->stapriv;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
psta = rtw_get_stainfo(pstapriv, bc_addr);
psta = rtw_get_stainfo(pstapriv, bc_addr);
return psta;
}
@ -572,7 +446,6 @@ struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
{
u8 res = true;
#ifdef CONFIG_88EU_AP_MODE
struct list_head *plist, *phead;
struct rtw_wlan_acl_node *paclnode;
u8 match = false;
@ -601,9 +474,7 @@ u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
else if (pacl_list->mode == 2)/* deny unless in accept list */
res = (match) ? true : false;
else
res = true;
#endif
res = true;
return res;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff