Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / wlan / ieee80211_output.c
1 #include <adf_os_types.h>
2 #include <adf_os_dma.h>
3 #include <adf_os_timer.h>
4 #include <adf_os_lock.h>
5 #include <adf_os_io.h>
6 #include <adf_os_mem.h>
7 #include <adf_os_module.h>
8 #include <adf_os_util.h>
9 #include <adf_os_stdtypes.h>
10 #include <adf_os_defer.h>
11 #include <adf_os_atomic.h>
12 #include <adf_nbuf.h>
13 #include <adf_net.h>
14
15 #include <if_llc.h>
16 #include <if_ethersubr.h>
17 #include "ieee80211_var.h"
18
19 #include "_ieee80211.h"
20 #include "ieee80211.h"
21 #include <wlan_hdr.h>
22
23 a_status_t
24 ieee80211_tgt_crypto_encap(struct ieee80211_frame *wh,
25                            struct ieee80211_node_target *ni,
26                            a_uint8_t keytype)
27 {
28 #define CRYPTO_KEY_TYPE_AES          2
29 #define CRYPTO_KEY_TYPE_TKIP         3
30 #define CRYPTO_KEY_TYPE_WAPI         4
31 #define IEEE80211_WLAN_HDR_LEN      24
32
33         a_uint8_t *iv = NULL;
34         a_uint16_t tmp;
35         a_uint16_t offset = IEEE80211_WLAN_HDR_LEN;
36         a_uint8_t b1, b2;
37
38         if (IEEE80211_QOS_HAS_SEQ(wh))
39                 offset += 4;  // pad for 4 byte alignment
40
41         iv = (a_uint8_t *) wh;
42         iv = iv + offset;
43
44         switch (keytype) {
45         case CRYPTO_KEY_TYPE_AES:
46                 ni->ni_iv16++;
47                 if (ni->ni_iv16 == 0)
48                 {
49                         ni->ni_iv32++;
50                 }
51
52                 *iv++ = (a_uint8_t) ni->ni_iv16;
53                 *iv++ = (a_uint8_t) (ni->ni_iv16 >> 8);
54                 *iv++ = 0x00;
55                 *iv++ |= 0x20;
56
57                 tmp = (a_uint16_t) ni->ni_iv32;
58                 *iv++ = (a_uint8_t) tmp;
59                 *iv++ = (a_uint8_t) (tmp >> 8);
60
61                 tmp = (a_uint16_t) (ni->ni_iv32 >> 16);
62                 *iv++ = (a_uint8_t) tmp;
63                 *iv = (a_uint8_t) (tmp >> 8);
64                 break;
65         case CRYPTO_KEY_TYPE_TKIP:
66                 ni->ni_iv16++;
67                 if (ni->ni_iv16 == 0)
68                 {
69                         ni->ni_iv32++;
70                 }
71
72                 b1 = (a_uint8_t) (ni->ni_iv16 >> 8);
73                 b2 = (b1 | 0x20) & 0x7f;
74
75                 *iv++ = b1;
76                 *iv++ = b2;
77
78                 *iv++ = (a_uint8_t) ni->ni_iv16;
79                 *iv++ |= 0x20;
80
81                 tmp = (a_uint16_t) ni->ni_iv32;
82                 *iv++ = (a_uint8_t) tmp;
83                 *iv++ = (a_uint8_t) (tmp >> 8);
84
85                 tmp = (a_uint16_t) (ni->ni_iv32 >> 16);
86                 *iv++ = (a_uint8_t) tmp;
87                 *iv = (a_uint8_t) (tmp >> 8);
88                 break;
89         default:
90                 break;
91         }
92
93         return 1;
94
95 #undef CRYPTO_KEY_TYPE_TKIP
96 #undef CRYPTO_KEY_TYPE_AES
97 #undef CRYPTO_KEY_TYPE_WAPI
98 #undef IEEE80211_WLAN_HDR_LEN
99 }
100
101 adf_os_export_symbol(ieee80211_tgt_crypto_encap);
102
103 #undef  IEEE80211_ADDR_LEN