/* IEEE 802.11 SoftMAC layer
*
*/
#include "ieee80211.h"
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include "dot11d.h"
u8 rsn_authen_cipher_suite[16][4] = {
{0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
{0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
{0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
{0x00,0x0F,0xAC,0x03}, //WRAP-historical
{0x00,0x0F,0xAC,0x04}, //CCMP
{0x00,0x0F,0xAC,0x05}, //WEP-104
};
short ieee80211_is_54g(struct ieee80211_network net)
{
return ((net.rates_ex_len > 0) || (net.rates_len > 4));
}
short ieee80211_is_shortslot(struct ieee80211_network net)
{
return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
}
/* returns the total length needed for pleacing the RATE MFIE
* tag and the EXTENDED RATE MFIE tag if needed.
* It encludes two bytes per tag for the tag itself and its len
*/
unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
{
unsigned int rate_len = 0;
if (ieee->modulation & IEEE80211_CCK_MODULATION)
rate_len = IEEE80211_CCK_RATE_LEN + 2;
if (ieee->modulation & IEEE80211_OFDM_MODULATION)
rate_len += IEEE80211_OFDM_RATE_LEN + 2;
return rate_len;
}
/* pleace the MFIE rate, tag to the memory (double) poined.
* Then it updates the pointer so that
* it points after the new MFIE tag added.
*/
void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
{
u8 *tag = *tag_p;
if (ieee->modulation & IEEE80211_CCK_MODULATION){
*tag++ = MFIE_TYPE_RATES;
*tag++ = 4;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
}
/* We may add an option for custom rates that specific HW might support */
*tag_p = tag;
}
void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
{
u8 *tag = *tag_p;
if (ieee->modulation & IEEE80211_OFDM_MODULATION){
*tag++ = MFIE_TYPE_RATES_EX;
*tag++ = 8;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
}
/* We may add an option for custom rates that specific HW might support */
*tag_p = tag;
}
void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
u8 *tag = *tag_p;
*tag++ = MFIE_TYPE_GENERIC; //0
*tag++ = 7;
*tag++ = 0x00;
*tag++ = 0x50;
*tag++ = 0xf2;
*tag++ = 0x02;//5
*tag++ = 0x00;
*tag++ = 0x01;
#ifdef SUPPORT_USPD
if(ieee->current_network.wmm_info & 0x80) {
*tag++ = 0x0f|MAX_SP_Len;
} else {
*tag++ = MAX_SP_Len;
}
#else
*tag++ = MAX_SP_Len;
#endif
*tag_p = tag;
}
void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
u8 *tag = *tag_p;
*tag++ = MFIE_TYPE_GENERIC; //0
*tag++ = 7;
*tag++ = 0x00;
*tag++ = 0xe0;
*tag++ = 0x4c;
*tag++ = 0x01;//5
*tag++ = 0x02;
*tag++ = 0x11;
*tag++ = 0x00;
*tag_p = tag;
printk(KERN_ALERT "This is enable turbo mode IE process\n");
}
void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
{
int nh;
nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
/*
* if the queue is full but we have newer frames then
* just overwrites the oldest.
*
* if (nh == ieee->mgmt_queue_tail)
* return -1;
*/
ieee->mgmt_queue_head = nh;
ieee->mgmt_queue_ring[nh] = skb;
//return 0;
}
struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
{
struct sk_buff *ret;
if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
return NULL;
ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
ieee->mgmt_queue_tail =
(ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
return ret;
}
void init_mgmt_queue(struct ieee80211_device *ieee)
{
ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
}
void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
{
unsigned long flags;
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
struct ieee80211_hdr_3addr *header=
(struct ieee80211_hdr_3addr *) skb->data;
spin_lock_irqsave(&ieee->lock, flags);
/* called with 2nd param 0, no mgmt lock required */
ieee80211_sta_wakeup(ieee,0);
if(single){
if(ieee->queue_stop){
enqueue_mgmt(ieee,skb);
}else{
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
if (ieee->seq_ctrl[0] == 0xFFF)
ieee->seq_ctrl[0] = 0;
else
ieee->seq_ctrl[0]++;
/* avoid watchdog triggers */
ieee->dev->trans_start = jiffies;
ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}else{
spin_unlock_irqrestore(&ieee->lock, flags);
spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
if (ieee->seq_ctrl[0] == 0xFFF)
ieee->seq_ctrl[0] = 0;
else
ieee->seq_ctrl[0]++;
/* avoid watchdog triggers */
ieee->dev->trans_start = jiffies;
ieee->softmac_hard_start_xmit(skb,ieee->dev);
spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
}
}
inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
{
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
struct ieee80211_hdr_3addr *header =
(struct ieee80211_hdr_3addr *) skb->data;
if(single){
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
if (ieee->seq_ctrl[0] == 0xFFF)
ieee->seq_ctrl[0] = 0;
else
ieee->seq_ctrl[0]++;
/* avoid watchdog triggers */
ieee->dev->trans_start = jiffies;
ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
}else{
header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
if (ieee->seq_ctrl[0] == 0xFFF)
ieee->seq_ctrl[0] = 0;
else
ieee->seq_ctrl[0]++;
/* avoid watchdog triggers */
ieee->dev->trans_start = jiffies;
ieee->softmac_hard_start_xmit(skb,ieee->dev);
}
// dev_kfree_skb_any(skb);//edit by thomas
}
//by amy for power save
inline struct sk_buff *ieee80211_disassociate_skb(
struct ieee80211_network *beacon,
struct ieee80211_device *ieee,
u8 asRsn)
{
struct sk_buff *skb;
struct ieee80211_disassoc_frame *disass;
skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
if (!skb)
return NULL;
disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame));
disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
disass->header.duration_id = 0;
memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
disass->reasoncode = asRsn;
return skb;
}
void
SendDisassociation(
struct ieee80211_device *ieee,
u8* asSta,
u8 asRsn
)
{
struct ieee80211_network *beacon = &ieee->current_network;
struct sk_buff *skb;
skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
if (skb){
softmac_mgmt_xmit(skb, ieee);
//dev_kfree_skb_any(skb);//edit by thomas
}
}
//by amy for power save
inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
{
unsigned int len,rate_len;
u8 *tag;
struct sk_buff *skb;
struct ieee80211_probe_request *req;
len = ieee->current_network.ssid_len;
rate_len = ieee80211_MFIE_rate_len(ieee);
skb = dev_alloc_skb(sizeof(
没有合适的资源?快使用搜索试试~ 我知道了~
ieee80211_softmac.rar_802.11 Linux
共1个文件
c:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 28 浏览量
2022-09-24
18:51:07
上传
评论
收藏 18KB RAR 举报
温馨提示
IEEE 802.11 SoftMAC layer driver for Linux.
资源推荐
资源详情
资源评论
收起资源包目录
ieee80211_softmac.rar (1个子文件)
ieee80211_softmac.c 79KB
共 1 条
- 1
资源评论
小波思基
- 粉丝: 72
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功