Commit 68762f3d authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [TG3]: Add TG3_FLAG_SUPPORT_MSI flag.
  [TG3]: Eliminate the TG3_FLAG_5701_REG_WRITE_BUG flag.
  [TG3]: Eliminate the TG3_FLAG_GOT_SERDES_FLOWCTL flag.
  [TG3]: Remove reset during MAC address changes.
  [TG3]: WoL fixes.
  [TG3]: Clear GPIO mask before storing.
  [TG3]: Improve NVRAM sizing.
  [TG3]: Fix TSO bugs.
  [MAC80211]: Add maintainers entry for mac80211.
  [MAC80211]: Add debugfs attributes.
  [MAC80211]: Add mac80211 wireless stack.
  [MAC80211]: Add generic include/linux/ieee80211.h
  [NETLINK]: Remove references to process ID
  [AF_IUCV]: Compile fix - adopt to skbuff changes.
parents 4f7a307d 7544b097
...@@ -2228,6 +2228,16 @@ M: philb@gnu.org ...@@ -2228,6 +2228,16 @@ M: philb@gnu.org
W: http://www.tazenda.demon.co.uk/phil/linux-hp W: http://www.tazenda.demon.co.uk/phil/linux-hp
S: Maintained S: Maintained
MAC80211
P: Jiri Benc
M: jbenc@suse.cz
P: Michael Wu
M: flamingice@sourmilk.net
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
T: git kernel.org:/pub/scm/linux/kernel/git/jbenc/mac80211.git
S: Maintained
MARVELL YUKON / SYSKONNECT DRIVER MARVELL YUKON / SYSKONNECT DRIVER
P: Mirko Lindner P: Mirko Lindner
M: mlindner@syskonnect.de M: mlindner@syskonnect.de
......
This diff is collapsed.
...@@ -131,6 +131,7 @@ ...@@ -131,6 +131,7 @@
#define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0_HW 0x5000
#define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A0 0x6000
#define CHIPREV_ID_5752_A1 0x6001 #define CHIPREV_ID_5752_A1 0x6001
#define CHIPREV_ID_5714_A2 0x9002
#define CHIPREV_ID_5906_A1 0xc001 #define CHIPREV_ID_5906_A1 0xc001
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07 #define ASIC_REV_5700 0x07
...@@ -2199,7 +2200,6 @@ struct tg3 { ...@@ -2199,7 +2200,6 @@ struct tg3 {
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
#define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_ENABLE_ASF 0x00000020
#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040
#define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
...@@ -2215,14 +2215,14 @@ struct tg3 { ...@@ -2215,14 +2215,14 @@ struct tg3 {
#define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_PCI_32BIT 0x00080000
#define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000
#define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000 #define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000
#define TG3_FLAG_SERDES_WOL_CAP 0x00400000 #define TG3_FLAG_WOL_CAP 0x00400000
#define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000
#define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_10_100_ONLY 0x01000000
#define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000
#define TG3_FLAG_IN_RESET_TASK 0x04000000 #define TG3_FLAG_IN_RESET_TASK 0x04000000
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000 #define TG3_FLAG_40BIT_DMA_BUG 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 #define TG3_FLAG_SUPPORT_MSI 0x20000000
#define TG3_FLAG_CHIP_RESETTING 0x40000000 #define TG3_FLAG_CHIP_RESETTING 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 tg3_flags2; u32 tg3_flags2;
......
/*
* IEEE 802.11 defines
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
* Copyright (c) 2005, Devicescape Software, Inc.
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef IEEE80211_H
#define IEEE80211_H
#include <linux/types.h>
#define FCS_LEN 4
#define IEEE80211_FCTL_VERS 0x0003
#define IEEE80211_FCTL_FTYPE 0x000c
#define IEEE80211_FCTL_STYPE 0x00f0
#define IEEE80211_FCTL_TODS 0x0100
#define IEEE80211_FCTL_FROMDS 0x0200
#define IEEE80211_FCTL_MOREFRAGS 0x0400
#define IEEE80211_FCTL_RETRY 0x0800
#define IEEE80211_FCTL_PM 0x1000
#define IEEE80211_FCTL_MOREDATA 0x2000
#define IEEE80211_FCTL_PROTECTED 0x4000
#define IEEE80211_FCTL_ORDER 0x8000
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
#define IEEE80211_FTYPE_MGMT 0x0000
#define IEEE80211_FTYPE_CTL 0x0004
#define IEEE80211_FTYPE_DATA 0x0008
/* management */
#define IEEE80211_STYPE_ASSOC_REQ 0x0000
#define IEEE80211_STYPE_ASSOC_RESP 0x0010
#define IEEE80211_STYPE_REASSOC_REQ 0x0020
#define IEEE80211_STYPE_REASSOC_RESP 0x0030
#define IEEE80211_STYPE_PROBE_REQ 0x0040
#define IEEE80211_STYPE_PROBE_RESP 0x0050
#define IEEE80211_STYPE_BEACON 0x0080
#define IEEE80211_STYPE_ATIM 0x0090
#define IEEE80211_STYPE_DISASSOC 0x00A0
#define IEEE80211_STYPE_AUTH 0x00B0
#define IEEE80211_STYPE_DEAUTH 0x00C0
#define IEEE80211_STYPE_ACTION 0x00D0
/* control */
#define IEEE80211_STYPE_PSPOLL 0x00A0
#define IEEE80211_STYPE_RTS 0x00B0
#define IEEE80211_STYPE_CTS 0x00C0
#define IEEE80211_STYPE_ACK 0x00D0
#define IEEE80211_STYPE_CFEND 0x00E0
#define IEEE80211_STYPE_CFENDACK 0x00F0
/* data */
#define IEEE80211_STYPE_DATA 0x0000
#define IEEE80211_STYPE_DATA_CFACK 0x0010
#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
#define IEEE80211_STYPE_NULLFUNC 0x0040
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
#define IEEE80211_STYPE_QOS_DATA 0x0080
#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090
#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0
#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0
#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0
#define IEEE80211_STYPE_QOS_CFACK 0x00D0
#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0
#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0
/* miscellaneous IEEE 802.11 constants */
#define IEEE80211_MAX_FRAG_THRESHOLD 2346
#define IEEE80211_MAX_RTS_THRESHOLD 2347
#define IEEE80211_MAX_AID 2007
#define IEEE80211_MAX_TIM_LEN 251
#define IEEE80211_MAX_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6.2.1.1.2.
The figure in section 7.1.2 suggests a body size of up to 2312
bytes is allowed, which is a bit confusing, I suspect this
represents the 2304 bytes of real data, plus a possible 8 bytes of
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
#define IEEE80211_MAX_SSID_LEN 32
struct ieee80211_hdr {
__le16 frame_control;
__le16 duration_id;
u8 addr1[6];
u8 addr2[6];
u8 addr3[6];
__le16 seq_ctrl;
u8 addr4[6];
} __attribute__ ((packed));
struct ieee80211_mgmt {
__le16 frame_control;
__le16 duration;
u8 da[6];
u8 sa[6];
u8 bssid[6];
__le16 seq_ctrl;
union {
struct {
__le16 auth_alg;
__le16 auth_transaction;
__le16 status_code;
/* possibly followed by Challenge text */
u8 variable[0];
} __attribute__ ((packed)) auth;
struct {
__le16 reason_code;
} __attribute__ ((packed)) deauth;
struct {
__le16 capab_info;
__le16 listen_interval;
/* followed by SSID and Supported rates */
u8 variable[0];
} __attribute__ ((packed)) assoc_req;
struct {
__le16 capab_info;
__le16 status_code;
__le16 aid;
/* followed by Supported rates */
u8 variable[0];
} __attribute__ ((packed)) assoc_resp, reassoc_resp;
struct {
__le16 capab_info;
__le16 listen_interval;
u8 current_ap[6];
/* followed by SSID and Supported rates */
u8 variable[0];
} __attribute__ ((packed)) reassoc_req;
struct {
__le16 reason_code;
} __attribute__ ((packed)) disassoc;
struct {
__le64 timestamp;
__le16 beacon_int;
__le16 capab_info;
/* followed by some of SSID, Supported rates,
* FH Params, DS Params, CF Params, IBSS Params, TIM */
u8 variable[0];
} __attribute__ ((packed)) beacon;
struct {
/* only variable items: SSID, Supported rates */
u8 variable[0];
} __attribute__ ((packed)) probe_req;
struct {
__le64 timestamp;
__le16 beacon_int;
__le16 capab_info;
/* followed by some of SSID, Supported rates,
* FH Params, DS Params, CF Params, IBSS Params */
u8 variable[0];
} __attribute__ ((packed)) probe_resp;
struct {
u8 category;
union {
struct {
u8 action_code;
u8 dialog_token;
u8 status_code;
u8 variable[0];
} __attribute__ ((packed)) wme_action;
struct{
u8 action_code;
u8 element_id;
u8 length;
u8 switch_mode;
u8 new_chan;
u8 switch_count;
} __attribute__((packed)) chan_switch;
} u;
} __attribute__ ((packed)) action;
} u;
} __attribute__ ((packed));
/* Control frames */
struct ieee80211_rts {
__le16 frame_control;
__le16 duration;
u8 ra[6];
u8 ta[6];
} __attribute__ ((packed));
struct ieee80211_cts {
__le16 frame_control;
__le16 duration;
u8 ra[6];
} __attribute__ ((packed));
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
#define WLAN_AUTH_FAST_BSS_TRANSITION 2
#define WLAN_AUTH_LEAP 128
#define WLAN_AUTH_CHALLENGE_LEN 128
#define WLAN_CAPABILITY_ESS (1<<0)
#define WLAN_CAPABILITY_IBSS (1<<1)
#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
#define WLAN_CAPABILITY_PRIVACY (1<<4)
#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
#define WLAN_CAPABILITY_PBCC (1<<6)
#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
/* 802.11h */
#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
#define WLAN_CAPABILITY_QOS (1<<9)
#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
/* Status codes */
enum ieee80211_statuscode {
WLAN_STATUS_SUCCESS = 0,
WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
WLAN_STATUS_CAPS_UNSUPPORTED = 10,
WLAN_STATUS_REASSOC_NO_ASSOC = 11,
WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
WLAN_STATUS_CHALLENGE_FAIL = 15,
WLAN_STATUS_AUTH_TIMEOUT = 16,
WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
WLAN_STATUS_ASSOC_DENIED_RATES = 18,
/* 802.11b */
WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
/* 802.11h */
WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
/* 802.11g */
WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
/* 802.11i */
WLAN_STATUS_INVALID_IE = 40,
WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
WLAN_STATUS_INVALID_AKMP = 43,
WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
};
/* Reason codes */
enum ieee80211_reasoncode {
WLAN_REASON_UNSPECIFIED = 1,
WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
WLAN_REASON_DEAUTH_LEAVING = 3,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
WLAN_REASON_DISASSOC_AP_BUSY = 5,
WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
/* 802.11h */
WLAN_REASON_DISASSOC_BAD_POWER = 10,
WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
/* 802.11i */
WLAN_REASON_INVALID_IE = 13,
WLAN_REASON_MIC_FAILURE = 14,
WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
WLAN_REASON_IE_DIFFERENT = 17,
WLAN_REASON_INVALID_GROUP_CIPHER = 18,
WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
WLAN_REASON_INVALID_AKMP = 20,
WLAN_REASON_UNSUPP_RSN_VERSION = 21,
WLAN_REASON_INVALID_RSN_IE_CAP = 22,
WLAN_REASON_IEEE8021X_FAILED = 23,
WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
};
/* Information Element IDs */
enum ieee80211_eid {
WLAN_EID_SSID = 0,
WLAN_EID_SUPP_RATES = 1,
WLAN_EID_FH_PARAMS = 2,
WLAN_EID_DS_PARAMS = 3,
WLAN_EID_CF_PARAMS = 4,
WLAN_EID_TIM = 5,
WLAN_EID_IBSS_PARAMS = 6,
WLAN_EID_CHALLENGE = 16,
/* 802.11d */
WLAN_EID_COUNTRY = 7,
WLAN_EID_HP_PARAMS = 8,
WLAN_EID_HP_TABLE = 9,
WLAN_EID_REQUEST = 10,
/* 802.11h */
WLAN_EID_PWR_CONSTRAINT = 32,
WLAN_EID_PWR_CAPABILITY = 33,
WLAN_EID_TPC_REQUEST = 34,
WLAN_EID_TPC_REPORT = 35,
WLAN_EID_SUPPORTED_CHANNELS = 36,
WLAN_EID_CHANNEL_SWITCH = 37,
WLAN_EID_MEASURE_REQUEST = 38,
WLAN_EID_MEASURE_REPORT = 39,
WLAN_EID_QUIET = 40,
WLAN_EID_IBSS_DFS = 41,
/* 802.11g */
WLAN_EID_ERP_INFO = 42,
WLAN_EID_EXT_SUPP_RATES = 50,
/* 802.11i */
WLAN_EID_RSN = 48,
WLAN_EID_WPA = 221,
WLAN_EID_GENERIC = 221,
WLAN_EID_VENDOR_SPECIFIC = 221,
WLAN_EID_QOS_PARAMETER = 222
};
/* cipher suite selectors */
#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00
#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01
#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02
/* reserved: 0x000FAC03 */
#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04
#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05
#define WLAN_MAX_KEY_LEN 32
#endif /* IEEE80211_H */
...@@ -31,7 +31,7 @@ struct sockaddr_nl ...@@ -31,7 +31,7 @@ struct sockaddr_nl
{ {
sa_family_t nl_family; /* AF_NETLINK */ sa_family_t nl_family; /* AF_NETLINK */
unsigned short nl_pad; /* zero */ unsigned short nl_pad; /* zero */
__u32 nl_pid; /* process pid */ __u32 nl_pid; /* port ID */
__u32 nl_groups; /* multicast groups mask */ __u32 nl_groups; /* multicast groups mask */
}; };
...@@ -41,7 +41,7 @@ struct nlmsghdr ...@@ -41,7 +41,7 @@ struct nlmsghdr
__u16 nlmsg_type; /* Message content */ __u16 nlmsg_type; /* Message content */
__u16 nlmsg_flags; /* Additional flags */ __u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */ __u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process PID */ __u32 nlmsg_pid; /* Sending process port ID */
}; };
/* Flags values */ /* Flags values */
......
This diff is collapsed.
...@@ -220,6 +220,7 @@ config FIB_RULES ...@@ -220,6 +220,7 @@ config FIB_RULES
menu "Wireless" menu "Wireless"
source "net/wireless/Kconfig" source "net/wireless/Kconfig"
source "net/mac80211/Kconfig"
source "net/ieee80211/Kconfig" source "net/ieee80211/Kconfig"
endmenu endmenu
......
...@@ -45,6 +45,8 @@ obj-$(CONFIG_ECONET) += econet/ ...@@ -45,6 +45,8 @@ obj-$(CONFIG_ECONET) += econet/
obj-$(CONFIG_VLAN_8021Q) += 8021q/ obj-$(CONFIG_VLAN_8021Q) += 8021q/
obj-$(CONFIG_IP_DCCP) += dccp/ obj-$(CONFIG_IP_DCCP) += dccp/
obj-$(CONFIG_IP_SCTP) += sctp/ obj-$(CONFIG_IP_SCTP) += sctp/
obj-y += wireless/
obj-$(CONFIG_MAC80211) += mac80211/
obj-$(CONFIG_IEEE80211) += ieee80211/ obj-$(CONFIG_IEEE80211) += ieee80211/
obj-$(CONFIG_TIPC) += tipc/ obj-$(CONFIG_TIPC) += tipc/
obj-$(CONFIG_NETLABEL) += netlabel/ obj-$(CONFIG_NETLABEL) += netlabel/
...@@ -53,5 +55,3 @@ obj-$(CONFIG_IUCV) += iucv/ ...@@ -53,5 +55,3 @@ obj-$(CONFIG_IUCV) += iucv/
ifeq ($(CONFIG_NET),y) ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o obj-$(CONFIG_SYSCTL) += sysctl_net.o
endif endif
obj-y += wireless/
...@@ -961,7 +961,7 @@ static void iucv_callback_connack(struct iucv_path *path, u8 ipuser[16]) ...@@ -961,7 +961,7 @@ static void iucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
} }
static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len, static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len,
struct sk_buff_head fragmented_skb_q) struct sk_buff_head *fragmented_skb_q)
{ {
int dataleft, size, copied = 0; int dataleft, size, copied = 0;
struct sk_buff *nskb; struct sk_buff *nskb;
...@@ -981,8 +981,8 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len, ...@@ -981,8 +981,8 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len,
copied += size; copied += size;
dataleft -= size; dataleft -= size;
nskb->h.raw = nskb->data; skb_reset_transport_header(nskb);
nskb->nh.raw = nskb->data; skb_reset_network_header(nskb);
nskb->len = size; nskb->len = size;
skb_queue_tail(fragmented_skb_q, nskb); skb_queue_tail(fragmented_skb_q, nskb);
......
config MAC80211
tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
depends on EXPERIMENTAL
select CRYPTO
select CRYPTO_ECB
select CRYPTO_ARC4
select CRYPTO_AES
select CRC32
select WIRELESS_EXT
select CFG80211
select NET_SCH_FIFO
---help---
This option enables the hardware independent IEEE 802.11
networking stack.
config MAC80211_LEDS
bool "Enable LED triggers"
depends on MAC80211 && LEDS_TRIGGERS
---help---
This option enables a few LED triggers for different
packet receive/transmit events.
config MAC80211_DEBUGFS
bool "Export mac80211 internals in DebugFS"
depends on MAC80211 && DEBUG_FS
---help---
Select this to see extensive information about
the internal state of mac80211 in debugfs.
Say N unless you know you need this.
config MAC80211_DEBUG
bool "Enable debugging output"
depends on MAC80211
---help---
This option will enable debug tracing output for the
ieee80211 network stack.
If you are not trying to debug or develop the ieee80211
subsystem, you most likely want to say N here.
config MAC80211_VERBOSE_DEBUG
bool "Verbose debugging output"
depends on MAC80211_DEBUG
config MAC80211_LOWTX_FRAME_DUMP
bool "Debug frame dumping"
depends on MAC80211_DEBUG
---help---
Selecting this option will cause the stack to
print a message for each frame that is handed
to the lowlevel driver for transmission. This
message includes all MAC addresses and the
frame control field.
If unsure, say N and insert the debugging code
you require into the driver you are debugging.
config TKIP_DEBUG
bool "TKIP debugging"
depends on MAC80211_DEBUG
config MAC80211_DEBUG_COUNTERS
bool "Extra statistics for TX/RX debugging"
depends on MAC80211_DEBUG
config MAC80211_IBSS_DEBUG
bool "Support for IBSS testing"
depends on MAC80211_DEBUG
---help---
Say Y here if you intend to debug the IBSS code.
config MAC80211_VERBOSE_PS_DEBUG
bool "Verbose powersave mode debugging"
depends on MAC80211_DEBUG
---help---
Say Y here to print out verbose powersave
mode debug messages.
obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
mac80211-objs := \
ieee80211.o \
ieee80211_ioctl.o \
sta_info.o \
wep.o \
wpa.o \
ieee80211_sta.o \
ieee80211_iface.o \
ieee80211_rate.o \
michael.o \
tkip.o \
aes_ccm.o \
wme.o \
ieee80211_cfg.o \
$(mac80211-objs-y)
/*
* Copyright 2003-2004, Instant802 Networks, Inc.
* Copyright 2005-2006, Devicescape Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <asm/scatterlist.h>
#include <net/mac80211.h>
#include "ieee80211_key.h"
#include "aes_ccm.h"
static void ieee80211_aes_encrypt(struct crypto_cipher *tfm,
const u8 pt[16], u8 ct[16])
{
crypto_cipher_encrypt_one(tfm, ct, pt);
}
static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
u8 *b, u8 *s_0, u8 *a)
{
int i;
ieee80211_aes_encrypt(tfm, b_0, b);
/* Extra Authenticate-only data (always two AES blocks) */
for (i = 0; i < AES_BLOCK_LEN; i++)
aad[i] ^= b[i];
ieee80211_aes_encrypt(tfm, aad, b);
aad += AES_BLOCK_LEN;
for (i = 0; i < AES_BLOCK_LEN; i++)
aad[i] ^= b[i];
ieee80211_aes_encrypt(tfm, aad, a);
/* Mask out bits from auth-only-b_0 */
b_0[0] &= 0x07;
/* S_0 is used to encrypt T (= MIC) */
b_0[14] = 0;
b_0[15] = 0;
ieee80211_aes_encrypt(tfm, b_0, s_0);
}
void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *b_0, u8 *aad, u8 *data, size_t data_len,
u8 *cdata, u8 *mic)
{
int i, j, last_len, num_blocks;
u8 *pos, *cpos, *b, *s_0, *e;
b = scratch;
s_0 = scratch + AES_BLOCK_LEN;
e = scratch + 2 * AES_BLOCK_LEN;
num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
last_len = data_len % AES_BLOCK_LEN;
aes_ccm_prepare(tfm, b_0, aad, b, s_0, b);
/* Process payload blocks */
pos = data;
cpos = cdata;
for (j = 1; j <= num_blocks; j++) {
int blen = (j == num_blocks && last_len) ?
last_len : AES_BLOCK_LEN;
/* Authentication followed by encryption */
for (i = 0; i < blen; i++)
b[i] ^= pos[i];
ieee80211_aes_encrypt(tfm, b, b);
b_0[14] = (j >> 8) & 0xff;
b_0[15] = j & 0xff;
ieee80211_aes_encrypt(tfm, b_0, e);
for (i = 0; i < blen; i++)
*cpos++ = *pos++ ^ e[i];
}
for (i = 0; i < CCMP_MIC_LEN; i++)
mic[i] = b[i] ^ s_0[i];
}
int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *b_0, u8 *aad, u8 *cdata, size_t data_len,
u8 *mic, u8 *data)
{
int i, j, last_len, num_blocks;
u8 *pos, *cpos, *b, *s_0, *a;
b = scratch;
s_0 = scratch + AES_BLOCK_LEN;
a = scratch + 2 * AES_BLOCK_LEN;
num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
last_len = data_len % AES_BLOCK_LEN;
aes_ccm_prepare(tfm, b_0, aad, b, s_0, a);
/* Process payload blocks */
cpos = cdata;
pos = data;
for (j = 1; j <= num_blocks; j++) {
int blen = (j == num_blocks && last_len) ?
last_len : AES_BLOCK_LEN;
/* Decryption followed by authentication */
b_0[14] = (j >> 8) & 0xff;
b_0[15] = j & 0xff;
ieee80211_aes_encrypt(tfm, b_0, b);
for (i = 0; i < blen; i++) {
*pos = *cpos++ ^ b[i];
a[i] ^= *pos++;
}
ieee80211_aes_encrypt(tfm, a, a);
}
for (i = 0; i < CCMP_MIC_LEN; i++) {
if ((mic[i] ^ s_0[i]) != a[i])
return -1;
}
return 0;
}
struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[])
{
struct crypto_cipher *tfm;
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
return NULL;
crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN);
return tfm;
}
void ieee80211_aes_key_free(struct crypto_cipher *tfm)
{
if (tfm)
crypto_free_cipher(tfm);
}
/*
* Copyright 2003-2004, Instant802 Networks, Inc.
* Copyright 2006, Devicescape Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef AES_CCM_H
#define AES_CCM_H
#include <linux/crypto.h>
#define AES_BLOCK_LEN 16
struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]);
void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *b_0, u8 *aad, u8 *data, size_t data_len,
u8 *cdata, u8 *mic);
int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
u8 *b_0, u8 *aad, u8 *cdata, size_t data_len,
u8 *mic, u8 *data);
void ieee80211_aes_key_free(struct crypto_cipher *tfm);
#endif /* AES_CCM_H */
This diff is collapsed.
#ifndef __MAC80211_DEBUGFS_H
#define __MAC80211_DEBUGFS_H
#ifdef CONFIG_MAC80211_DEBUGFS
extern void debugfs_hw_add(struct ieee80211_local *local);
extern void debugfs_hw_del(struct ieee80211_local *local);
extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
#else
static inline void debugfs_hw_add(struct ieee80211_local *local)
{
return;
}
static inline void debugfs_hw_del(struct ieee80211_local *local) {}
#endif
#endif /* __MAC80211_DEBUGFS_H */
/*
* Copyright 2003-2005 Devicescape Software, Inc.
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kobject.h>
#include "ieee80211_i.h"
#include "ieee80211_key.h"
#include "debugfs.h"
#include "debugfs_key.h"
#define KEY_READ(name, buflen, format_string) \
static ssize_t key_##name##_read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
char buf[buflen]; \
struct ieee80211_key *key = file->private_data; \
int res = scnprintf(buf, buflen, format_string, key->name); \
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
#define KEY_READ_D(name) KEY_READ(name, 20, "%d\n")
#define KEY_OPS(name) \
static const struct file_operations key_ ##name## _ops = { \
.read = key_##name##_read, \
.open = mac80211_open_file_generic, \
}
#define KEY_FILE(name, format) \
KEY_READ_##format(name) \
KEY_OPS(name)
KEY_FILE(keylen, D);
KEY_FILE(force_sw_encrypt, D);
KEY_FILE(keyidx, D);
KEY_FILE(hw_key_idx, D);
KEY_FILE(tx_rx_count, D);
static ssize_t key_algorithm_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
char *alg;
struct ieee80211_key *key = file->private_data;
switch (key->alg) {
case ALG_WEP:
alg = "WEP\n";
break;
case ALG_TKIP:
alg = "TKIP\n";
break;
case ALG_CCMP:
alg = "CCMP\n";
break;
default:
return 0;
}
return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg));
}
KEY_OPS(algorithm);
static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const u8 *tpn;
char buf[20];
int len;
struct ieee80211_key *key = file->private_data;
switch (key->alg) {
case ALG_WEP:
len = scnprintf(buf, sizeof(buf), "\n");
case ALG_TKIP:
len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
key->u.tkip.iv32,
key->u.tkip.iv16);
case ALG_CCMP:
tpn = key->u.ccmp.tx_pn;
len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
default:
return 0;
}
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
KEY_OPS(tx_spec);
static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_key *key = file->private_data;
char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
int i, len;
const u8 *rpn;
switch (key->alg) {
case ALG_WEP:
len = scnprintf(buf, sizeof(buf), "\n");
case ALG_TKIP:
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p,
"%08x %04x\n",
key->u.tkip.iv32_rx[i],
key->u.tkip.iv16_rx[i]);
len = p - buf;
case ALG_CCMP:
for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
rpn = key->u.ccmp.rx_pn[i];
p += scnprintf(p, sizeof(buf)+buf-p,
"%02x%02x%02x%02x%02x%02x\n",
rpn[0], rpn[1], rpn[2],
rpn[3], rpn[4], rpn[5]);
}
len = p - buf;
default:
return 0;
}
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
KEY_OPS(rx_spec);
static ssize_t key_replays_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_key *key = file->private_data;
char buf[20];
int len;
if (key->alg != ALG_CCMP)
return 0;
len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
KEY_OPS(replays);
static ssize_t key_key_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_key *key = file->private_data;
int i, res, bufsize = 2*key->keylen+2;
char *buf = kmalloc(bufsize, GFP_KERNEL);
char *p = buf;
for (i = 0; i < key->keylen; i++)
p += scnprintf(p, bufsize+buf-p, "%02x", key->key[i]);
p += scnprintf(p, bufsize+buf-p, "\n");
res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
kfree(buf);
return res;
}
KEY_OPS(key);
#define DEBUGFS_ADD(name) \
key->debugfs.name = debugfs_create_file(#name, 0400,\
key->debugfs.dir, key, &key_##name##_ops);
void ieee80211_debugfs_key_add(struct ieee80211_local *local,
struct ieee80211_key *key)
{
char buf[20];
if (!local->debugfs.keys)
return;
sprintf(buf, "%d", key->keyidx);
key->debugfs.dir = debugfs_create_dir(buf,
local->debugfs.keys);
if (!key->debugfs.dir)
return;
DEBUGFS_ADD(keylen);
DEBUGFS_ADD(force_sw_encrypt);
DEBUGFS_ADD(keyidx);
DEBUGFS_ADD(hw_key_idx);
DEBUGFS_ADD(tx_rx_count);
DEBUGFS_ADD(algorithm);
DEBUGFS_ADD(tx_spec);
DEBUGFS_ADD(rx_spec);
DEBUGFS_ADD(replays);
DEBUGFS_ADD(key);
};
#define DEBUGFS_DEL(name) \
debugfs_remove(key->debugfs.name); key->debugfs.name = NULL;
void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
{
if (!key)
return;
DEBUGFS_DEL(keylen);
DEBUGFS_DEL(force_sw_encrypt);
DEBUGFS_DEL(keyidx);
DEBUGFS_DEL(hw_key_idx);
DEBUGFS_DEL(tx_rx_count);
DEBUGFS_DEL(algorithm);
DEBUGFS_DEL(tx_spec);
DEBUGFS_DEL(rx_spec);
DEBUGFS_DEL(replays);
DEBUGFS_DEL(key);
debugfs_remove(key->debugfs.stalink);
key->debugfs.stalink = NULL;
debugfs_remove(key->debugfs.dir);
key->debugfs.dir = NULL;
}
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
{
char buf[50];
if (!sdata->debugfsdir)
return;
sprintf(buf, "../keys/%d", sdata->default_key->keyidx);
sdata->debugfs.default_key =
debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
}
void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
{
if (!sdata)
return;
debugfs_remove(sdata->debugfs.default_key);
sdata->debugfs.default_key = NULL;
}
void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
struct sta_info *sta)
{
char buf[50];
if (!key->debugfs.dir)
return;
sprintf(buf, "../sta/" MAC_FMT, MAC_ARG(sta->addr));
key->debugfs.stalink =
debugfs_create_symlink("station", key->debugfs.dir, buf);
}
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
struct sta_info *sta)
{
debugfs_remove(key->debugfs.stalink);
key->debugfs.stalink = NULL;
}
#ifndef __MAC80211_DEBUGFS_KEY_H
#define __MAC80211_DEBUGFS_KEY_H
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_debugfs_key_add(struct ieee80211_local *local,
struct ieee80211_key *key);
void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
struct sta_info *sta);
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
struct sta_info *sta);
#else
static inline void ieee80211_debugfs_key_add(struct ieee80211_local *local,
struct ieee80211_key *key)
{}
static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
{}
static inline void ieee80211_debugfs_key_add_default(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_key_remove_default(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_key_sta_link(
struct ieee80211_key *key, struct sta_info *sta)
{}
static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
struct sta_info *sta)
{}
#endif
#endif /* __MAC80211_DEBUGFS_KEY_H */
This diff is collapsed.
/* routines exported for debugfs handling */
#ifndef __IEEE80211_DEBUGFS_NETDEV_H
#define __IEEE80211_DEBUGFS_NETDEV_H
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata);
void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata,
int oldtype);
void ieee80211_debugfs_netdev_init(void);
void ieee80211_debugfs_netdev_exit(void);
#else
static inline void ieee80211_debugfs_add_netdev(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_remove_netdev(
struct ieee80211_sub_if_data *sdata)
{}
static inline void ieee80211_debugfs_change_if_type(
struct ieee80211_sub_if_data *sdata, int oldtype)
{}
static inline void ieee80211_debugfs_netdev_init(void)
{}
static inline void ieee80211_debugfs_netdev_exit(void)
{}
#endif
#endif /* __IEEE80211_DEBUGFS_NETDEV_H */
/*
* Copyright 2003-2005 Devicescape Software, Inc.
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/debugfs.h>
#include <linux/ieee80211.h>
#include "ieee80211_i.h"
#include "debugfs.h"
#include "debugfs_sta.h"
#include "sta_info.h"
/* sta attributtes */
#define STA_READ(name, buflen, field, format_string) \
static ssize_t sta_ ##name## _read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
int res; \
struct sta_info *sta = file->private_data; \
char buf[buflen]; \
res = scnprintf(buf, buflen, format_string, sta->field); \
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n")
#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n")
#define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n")
#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n")
#define STA_READ_RATE(name, field) \
static ssize_t sta_##name##_read(struct file *file, \
char __user *userbuf, \
size_t count, loff_t *ppos) \
{ \
struct sta_info *sta = file->private_data; \
struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\
struct ieee80211_hw_mode *mode = local->oper_hw_mode; \
char buf[20]; \
int res = scnprintf(buf, sizeof(buf), "%d\n", \
(sta->field >= 0 && \
sta->field < mode->num_rates) ? \
mode->rates[sta->field].rate : -1); \
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
}
#define STA_OPS(name) \
static const struct file_operations sta_ ##name## _ops = { \
.read = sta_##name##_read, \
.open = mac80211_open_file_generic, \
}
#define STA_FILE(name, field, format) \
STA_READ_##format(name, field) \
STA_OPS(name)
STA_FILE(aid, aid, D);
STA_FILE(key_idx_compression, key_idx_compression, D);
STA_FILE(dev, dev->name, S);
STA_FILE(vlan_id, vlan_id, D);
STA_FILE(rx_packets, rx_packets, LU);
STA_FILE(tx_packets, tx_packets, LU);
STA_FILE(rx_bytes, rx_bytes, LU);
STA_FILE(tx_bytes, tx_bytes, LU);
STA_FILE(rx_duplicates, num_duplicates, LU);
STA_FILE(rx_fragments, rx_fragments, LU);
STA_FILE(rx_dropped, rx_dropped, LU);
STA_FILE(tx_fragments, tx_fragments, LU);
STA_FILE(tx_filtered, tx_filtered_count, LU);
STA_FILE(txrate, txrate, RATE);
STA_FILE(last_txrate, last_txrate, RATE);
STA_FILE(tx_retry_failed, tx_retry_failed, LU);
STA_FILE(tx_retry_count, tx_retry_count, LU);
STA_FILE(last_rssi, last_rssi, D);
STA_FILE(last_signal, last_signal, D);
STA_FILE(last_noise, last_noise, D);
STA_FILE(channel_use, channel_use, D);
STA_FILE(wep_weak_iv_count, wep_weak_iv_count, D);
static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[100];
struct sta_info *sta = file->private_data;
int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "",
sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
sta->flags & WLAN_STA_PS ? "PS\n" : "",
sta->flags & WLAN_STA_TIM ? "TIM\n" : "",
sta->flags & WLAN_STA_PERM ? "PERM\n" : "",
sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
sta->flags & WLAN_STA_WME ? "WME\n" : "",
sta->flags & WLAN_STA_WDS ? "WDS\n" : "");
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(flags);
static ssize_t sta_num_ps_buf_frames_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[20];
struct sta_info *sta = file->private_data;
int res = scnprintf(buf, sizeof(buf), "%u\n",
skb_queue_len(&sta->ps_tx_buf));
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(num_ps_buf_frames);
static ssize_t sta_last_ack_rssi_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[100];
struct sta_info *sta = file->private_data;
int res = scnprintf(buf, sizeof(buf), "%d %d %d\n",
sta->last_ack_rssi[0],
sta->last_ack_rssi[1],
sta->last_ack_rssi[2]);
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(last_ack_rssi);
static ssize_t sta_last_ack_ms_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[20];
struct sta_info *sta = file->private_data;
int res = scnprintf(buf, sizeof(buf), "%d\n",
sta->last_ack ?
jiffies_to_msecs(jiffies - sta->last_ack) : -1);
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(last_ack_ms);
static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[20];
struct sta_info *sta = file->private_data;
int res = scnprintf(buf, sizeof(buf), "%d\n",
jiffies_to_msecs(jiffies - sta->last_rx));
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(inactive_ms);
static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
int i;
struct sta_info *sta = file->private_data;
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
sta->last_seq_ctrl[i]);
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
STA_OPS(last_seq_ctrl);
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
int i;
struct sta_info *sta = file->private_data;
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
sta->wme_rx_queue[i]);
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
STA_OPS(wme_rx_queue);
static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
int i;
struct sta_info *sta = file->private_data;
for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
sta->wme_tx_queue[i]);
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
STA_OPS(wme_tx_queue);
#endif
#define DEBUGFS_ADD(name) \
sta->debugfs.name = debugfs_create_file(#name, 0444, \
sta->debugfs.dir, sta, &sta_ ##name## _ops);
#define DEBUGFS_DEL(name) \
debugfs_remove(sta->debugfs.name);\
sta->debugfs.name = NULL;
void ieee80211_sta_debugfs_add(struct sta_info *sta)
{
char buf[3*6];
struct dentry *stations_dir = sta->local->debugfs.stations;
if (!stations_dir)
return;
sprintf(buf, MAC_FMT, MAC_ARG(sta->addr));
sta->debugfs.dir = debugfs_create_dir(buf, stations_dir);
if (!sta->debugfs.dir)
return;
DEBUGFS_ADD(flags);
DEBUGFS_ADD(num_ps_buf_frames);
DEBUGFS_ADD(last_ack_rssi);
DEBUGFS_ADD(last_ack_ms);
DEBUGFS_ADD(inactive_ms);
DEBUGFS_ADD(last_seq_ctrl);
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
DEBUGFS_ADD(wme_rx_queue);
DEBUGFS_ADD(wme_tx_queue);
#endif
}
void ieee80211_sta_debugfs_remove(struct sta_info *sta)
{
DEBUGFS_DEL(flags);
DEBUGFS_DEL(num_ps_buf_frames);
DEBUGFS_DEL(last_ack_rssi);
DEBUGFS_DEL(last_ack_ms);
DEBUGFS_DEL(inactive_ms);
DEBUGFS_DEL(last_seq_ctrl);
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
DEBUGFS_DEL(wme_rx_queue);
DEBUGFS_DEL(wme_tx_queue);
#endif
debugfs_remove(sta->debugfs.dir);
sta->debugfs.dir = NULL;
}
#ifndef __MAC80211_DEBUGFS_STA_H
#define __MAC80211_DEBUGFS_STA_H
#ifdef CONFIG_MAC80211_DEBUGFS
void ieee80211_sta_debugfs_add(struct sta_info *sta);
void ieee80211_sta_debugfs_remove(struct sta_info *sta);
#else
static inline void ieee80211_sta_debugfs_add(struct sta_info *sta) {}
static inline void ieee80211_sta_debugfs_remove(struct sta_info *sta) {}
#endif
#endif /* __MAC80211_DEBUGFS_STA_H */
/*
* Host AP (software wireless LAN access point) user space daemon for
* Host AP kernel driver
* Copyright 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
* Copyright 2002-2004, Instant802 Networks, Inc.
* Copyright 2005, Devicescape Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef HOSTAPD_IOCTL_H
#define HOSTAPD_IOCTL_H
#ifdef __KERNEL__
#include <linux/types.h>
#endif /* __KERNEL__ */
#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
#define PRISM2_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 3)
/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes:
* This table is no longer added to, the whole sub-ioctl
* mess shall be deleted completely. */
enum {
PRISM2_PARAM_IEEE_802_1X = 23,
PRISM2_PARAM_ANTSEL_TX = 24,
PRISM2_PARAM_ANTSEL_RX = 25,
/* Instant802 additions */
PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES = 1001,
PRISM2_PARAM_DROP_UNENCRYPTED = 1002,
PRISM2_PARAM_PREAMBLE = 1003,
PRISM2_PARAM_SHORT_SLOT_TIME = 1006,
PRISM2_PARAM_NEXT_MODE = 1008,
PRISM2_PARAM_CLEAR_KEYS = 1009,
PRISM2_PARAM_RADIO_ENABLED = 1010,
PRISM2_PARAM_ANTENNA_MODE = 1013,
PRISM2_PARAM_STAT_TIME = 1016,
PRISM2_PARAM_STA_ANTENNA_SEL = 1017,
PRISM2_PARAM_FORCE_UNICAST_RATE = 1018,
PRISM2_PARAM_RATE_CTRL_NUM_UP = 1019,
PRISM2_PARAM_RATE_CTRL_NUM_DOWN = 1020,
PRISM2_PARAM_MAX_RATECTRL_RATE = 1021,
PRISM2_PARAM_TX_POWER_REDUCTION = 1022,
PRISM2_PARAM_KEY_TX_RX_THRESHOLD = 1024,
PRISM2_PARAM_DEFAULT_WEP_ONLY = 1026,
PRISM2_PARAM_WIFI_WME_NOACK_TEST = 1033,
PRISM2_PARAM_SCAN_FLAGS = 1035,
PRISM2_PARAM_HW_MODES = 1036,
PRISM2_PARAM_CREATE_IBSS = 1037,
PRISM2_PARAM_WMM_ENABLED = 1038,
PRISM2_PARAM_MIXED_CELL = 1039,
PRISM2_PARAM_RADAR_DETECT = 1043,
PRISM2_PARAM_SPECTRUM_MGMT = 1044,
};
enum {
IEEE80211_KEY_MGMT_NONE = 0,
IEEE80211_KEY_MGMT_IEEE8021X = 1,
IEEE80211_KEY_MGMT_WPA_PSK = 2,
IEEE80211_KEY_MGMT_WPA_EAP = 3,
};
/* Data structures used for get_hw_features ioctl */
struct hostapd_ioctl_hw_modes_hdr {
int mode;
int num_channels;
int num_rates;
};
struct ieee80211_channel_data {
short chan; /* channel number (IEEE 802.11) */
short freq; /* frequency in MHz */
int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */
};
struct ieee80211_rate_data {
int rate; /* rate in 100 kbps */
int flags; /* IEEE80211_RATE_ flags */
};
/* ADD_IF, REMOVE_IF, and UPDATE_IF 'type' argument */
enum {
HOSTAP_IF_WDS = 1, HOSTAP_IF_VLAN = 2, HOSTAP_IF_BSS = 3,
HOSTAP_IF_STA = 4
};
struct hostapd_if_wds {
u8 remote_addr[ETH_ALEN];
};
struct hostapd_if_vlan {
u8 id;
};
struct hostapd_if_bss {
u8 bssid[ETH_ALEN];
};
struct hostapd_if_sta {
};
#endif /* HOSTAPD_IOCTL_H */
This diff is collapsed.
/*
* mac80211 configuration hooks for cfg80211
*
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
*
* This file is GPLv2 as found in COPYING.
*/
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
#include "ieee80211_cfg.h"
static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
unsigned int type)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
int itype;
if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
return -ENODEV;
switch (type) {
case NL80211_IFTYPE_UNSPECIFIED:
itype = IEEE80211_IF_TYPE_STA;
break;
case NL80211_IFTYPE_ADHOC:
itype = IEEE80211_IF_TYPE_IBSS;
break;
case NL80211_IFTYPE_STATION:
itype = IEEE80211_IF_TYPE_STA;
break;
case NL80211_IFTYPE_MONITOR:
itype = IEEE80211_IF_TYPE_MNTR;
break;
default:
return -EINVAL;
}
return ieee80211_if_add(local->mdev, name, NULL, itype);
}
static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct net_device *dev;
char *name;
if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
return -ENODEV;
dev = dev_get_by_index(ifindex);
if (!dev)
return 0;
name = dev->name;
dev_put(dev);
return ieee80211_if_remove(local->mdev, name, -1);
}
struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
};
/*
* mac80211 configuration hooks for cfg80211
*/
#ifndef __IEEE80211_CFG_H
#define __IEEE80211_CFG_H
extern struct cfg80211_ops mac80211_config_ops;
#endif /* __IEEE80211_CFG_H */
/*
* IEEE 802.11 driver (80211.o) -- hostapd interface
* Copyright 2002-2004, Instant802 Networks, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef IEEE80211_COMMON_H
#define IEEE80211_COMMON_H
#include <linux/types.h>
/*
* This is common header information with user space. It is used on all
* frames sent to wlan#ap interface.
*/
#define IEEE80211_FI_VERSION 0x80211001
struct ieee80211_frame_info {
__be32 version;
__be32 length;
__be64 mactime;
__be64 hosttime;
__be32 phytype;
__be32 channel;
__be32 datarate;
__be32 antenna;
__be32 priority;
__be32 ssi_type;
__be32 ssi_signal;
__be32 ssi_noise;
__be32 preamble;
__be32 encoding;
/* Note: this structure is otherwise identical to capture format used
* in linux-wlan-ng, but this additional field is used to provide meta
* data about the frame to hostapd. This was the easiest method for
* providing this information, but this might change in the future. */
__be32 msg_type;
} __attribute__ ((packed));
enum ieee80211_msg_type {
ieee80211_msg_normal = 0,
ieee80211_msg_tx_callback_ack = 1,
ieee80211_msg_tx_callback_fail = 2,
ieee80211_msg_passive_scan = 3,
ieee80211_msg_wep_frame_unknown_key = 4,
ieee80211_msg_michael_mic_failure = 5,
/* hole at 6, was monitor but never sent to userspace */
ieee80211_msg_sta_not_assoc = 7,
ieee80211_msg_set_aid_for_sta = 8 /* used by Intersil MVC driver */,
ieee80211_msg_key_threshold_notification = 9,
ieee80211_msg_radar = 11,
};
struct ieee80211_msg_set_aid_for_sta {
char sta_address[ETH_ALEN];
u16 aid;
};
struct ieee80211_msg_key_notification {
int tx_rx_count;
char ifname[IFNAMSIZ];
u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */
};
enum ieee80211_phytype {
ieee80211_phytype_fhss_dot11_97 = 1,
ieee80211_phytype_dsss_dot11_97 = 2,
ieee80211_phytype_irbaseband = 3,
ieee80211_phytype_dsss_dot11_b = 4,
ieee80211_phytype_pbcc_dot11_b = 5,
ieee80211_phytype_ofdm_dot11_g = 6,
ieee80211_phytype_pbcc_dot11_g = 7,
ieee80211_phytype_ofdm_dot11_a = 8,
ieee80211_phytype_dsss_dot11_turbog = 255,
ieee80211_phytype_dsss_dot11_turbo = 256,
};
enum ieee80211_ssi_type {
ieee80211_ssi_none = 0,
ieee80211_ssi_norm = 1, /* normalized, 0-1000 */
ieee80211_ssi_dbm = 2,
ieee80211_ssi_raw = 3, /* raw SSI */
};
struct ieee80211_radar_info {
int channel;
int radar;
int radar_type;
};
#endif /* IEEE80211_COMMON_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2002-2004, Instant802 Networks, Inc.
* Copyright 2005, Devicescape Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef IEEE80211_KEY_H
#define IEEE80211_KEY_H
#include <linux/types.h>
#include <linux/kref.h>
#include <linux/crypto.h>
#include <net/mac80211.h>
/* ALG_TKIP
* struct ieee80211_key::key is encoded as a 256-bit (32 byte) data block:
* Temporal Encryption Key (128 bits)
* Temporal Authenticator Tx MIC Key (64 bits)
* Temporal Authenticator Rx MIC Key (64 bits)
*/
#define WEP_IV_LEN 4
#define WEP_ICV_LEN 4
#define ALG_TKIP_KEY_LEN 32
/* Starting offsets for each key */
#define ALG_TKIP_TEMP_ENCR_KEY 0
#define ALG_TKIP_TEMP_AUTH_TX_MIC_KEY 16
#define ALG_TKIP_TEMP_AUTH_RX_MIC_KEY 24
#define TKIP_IV_LEN 8
#define TKIP_ICV_LEN 4
#define ALG_CCMP_KEY_LEN 16
#define CCMP_HDR_LEN 8
#define CCMP_MIC_LEN 8
#define CCMP_TK_LEN 16
#define CCMP_PN_LEN 6
#define NUM_RX_DATA_QUEUES 17
struct ieee80211_key {
struct kref kref;
int hw_key_idx; /* filled and used by low-level driver */
ieee80211_key_alg alg;
union {
struct {
/* last used TSC */
u32 iv32;
u16 iv16;
u16 p1k[5];
int tx_initialized;
/* last received RSC */
u32 iv32_rx[NUM_RX_DATA_QUEUES];
u16 iv16_rx[NUM_RX_DATA_QUEUES];
u16 p1k_rx[NUM_RX_DATA_QUEUES][5];
int rx_initialized[NUM_RX_DATA_QUEUES];
} tkip;
struct {
u8 tx_pn[6];
u8 rx_pn[NUM_RX_DATA_QUEUES][6];
struct crypto_cipher *tfm;
u32 replays; /* dot11RSNAStatsCCMPReplays */
/* scratch buffers for virt_to_page() (crypto API) */
#ifndef AES_BLOCK_LEN
#define AES_BLOCK_LEN 16
#endif
u8 tx_crypto_buf[6 * AES_BLOCK_LEN];
u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
} ccmp;
} u;
int tx_rx_count; /* number of times this key has been used */
int keylen;
/* if the low level driver can provide hardware acceleration it should
* clear this flag */
unsigned int force_sw_encrypt:1;
unsigned int default_tx_key:1; /* This key is the new default TX key
* (used only for broadcast keys). */
s8 keyidx; /* WEP key index */
#ifdef CONFIG_MAC80211_DEBUGFS
struct {
struct dentry *stalink;
struct dentry *dir;
struct dentry *keylen;
struct dentry *force_sw_encrypt;
struct dentry *keyidx;
struct dentry *hw_key_idx;
struct dentry *tx_rx_count;
struct dentry *algorithm;
struct dentry *tx_spec;
struct dentry *rx_spec;
struct dentry *replays;
struct dentry *key;
} debugfs;
#endif
u8 key[0];
};
#endif /* IEEE80211_KEY_H */
/*
* Copyright 2006, Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* just for IFNAMSIZ */
#include <linux/if.h>
#include "ieee80211_led.h"
void ieee80211_led_rx(struct ieee80211_local *local)
{
if (unlikely(!local->rx_led))
return;
if (local->rx_led_counter++ % 2 == 0)
led_trigger_event(local->rx_led, LED_OFF);
else
led_trigger_event(local->rx_led, LED_FULL);
}
/* q is 1 if a packet was enqueued, 0 if it has been transmitted */
void ieee80211_led_tx(struct ieee80211_local *local, int q)
{
if (unlikely(!local->tx_led))
return;
/* not sure how this is supposed to work ... */
local->tx_led_counter += 2*q-1;
if (local->tx_led_counter % 2 == 0)
led_trigger_event(local->tx_led, LED_OFF);
else
led_trigger_event(local->tx_led, LED_FULL);
}
void ieee80211_led_init(struct ieee80211_local *local)
{
local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (!local->rx_led)
return;
snprintf(local->rx_led_name, sizeof(local->rx_led_name),
"%srx", wiphy_name(local->hw.wiphy));
local->rx_led->name = local->rx_led_name;
if (led_trigger_register(local->rx_led)) {
kfree(local->rx_led);
local->rx_led = NULL;
}
local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (!local->tx_led)
return;
snprintf(local->tx_led_name, sizeof(local->tx_led_name),
"%stx", wiphy_name(local->hw.wiphy));
local->tx_led->name = local->tx_led_name;
if (led_trigger_register(local->tx_led)) {
kfree(local->tx_led);
local->tx_led = NULL;
}
}
void ieee80211_led_exit(struct ieee80211_local *local)
{
if (local->tx_led) {
led_trigger_unregister(local->tx_led);
kfree(local->tx_led);
}
if (local->rx_led) {
led_trigger_unregister(local->rx_led);
kfree(local->rx_led);
}
}
char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
if (local->tx_led)
return local->tx_led_name;
return NULL;
}
EXPORT_SYMBOL(__ieee80211_get_tx_led_name);
char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
if (local->rx_led)
return local->rx_led_name;
return NULL;
}
EXPORT_SYMBOL(__ieee80211_get_rx_led_name);
/*
* Copyright 2006, Johannes Berg <johannes@sipsolutions.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/leds.h>
#include "ieee80211_i.h"
#ifdef CONFIG_MAC80211_LEDS
extern void ieee80211_led_rx(struct ieee80211_local *local);
extern void ieee80211_led_tx(struct ieee80211_local *local, int q);
extern void ieee80211_led_init(struct ieee80211_local *local);
extern void ieee80211_led_exit(struct ieee80211_local *local);
#else
static inline void ieee80211_led_rx(struct ieee80211_local *local)
{
}
static inline void ieee80211_led_tx(struct ieee80211_local *local, int q)
{
}
static inline void ieee80211_led_init(struct ieee80211_local *local)
{
}
static inline void ieee80211_led_exit(struct ieee80211_local *local)
{
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Michael MIC implementation - optimized for TKIP MIC operations
* Copyright 2002-2003, Instant802 Networks, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include "michael.h"
static inline u32 rotr(u32 val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
static inline u32 rotl(u32 val, int bits)
{
return (val << bits) | (val >> (32 - bits));
}
static inline u32 xswap(u32 val)
{
return ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8);
}
#define michael_block(l, r) \
do { \
r ^= rotl(l, 17); \
l += r; \
r ^= xswap(l); \
l += r; \
r ^= rotl(l, 3); \
l += r; \
r ^= rotr(l, 2); \
l += r; \
} while (0)
static inline u32 michael_get32(u8 *data)
{
return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
static inline void michael_put32(u32 val, u8 *data)
{
data[0] = val & 0xff;
data[1] = (val >> 8) & 0xff;
data[2] = (val >> 16) & 0xff;
data[3] = (val >> 24) & 0xff;
}
void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority,
u8 *data, size_t data_len, u8 *mic)
{
u32 l, r, val;
size_t block, blocks, left;
l = michael_get32(key);
r = michael_get32(key + 4);
/* A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC
* calculation, but it is _not_ transmitted */
l ^= michael_get32(da);
michael_block(l, r);
l ^= da[4] | (da[5] << 8) | (sa[0] << 16) | (sa[1] << 24);
michael_block(l, r);
l ^= michael_get32(&sa[2]);
michael_block(l, r);
l ^= priority;
michael_block(l, r);
/* Real data */
blocks = data_len / 4;
left = data_len % 4;
for (block = 0; block < blocks; block++) {
l ^= michael_get32(&data[block * 4]);
michael_block(l, r);
}
/* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make
* total length a multiple of 4. */
val = 0x5a;
while (left > 0) {
val <<= 8;
left--;
val |= data[blocks * 4 + left];
}
l ^= val;
michael_block(l, r);
/* last block is zero, so l ^ 0 = l */
michael_block(l, r);
michael_put32(l, mic);
michael_put32(r, mic + 4);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment