| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* |
| 3 | * PS3 gelic network driver. |
| 4 | * |
| 5 | * Copyright (C) 2007 Sony Computer Entertainment Inc. |
| 6 | * Copyright 2007 Sony Corporation |
| 7 | */ |
| 8 | #ifndef _GELIC_WIRELESS_H |
| 9 | #define _GELIC_WIRELESS_H |
| 10 | |
| 11 | #include <linux/wireless.h> |
| 12 | #include <net/iw_handler.h> |
| 13 | |
| 14 | |
| 15 | /* return value from GELIC_LV1_GET_WLAN_EVENT netcontrol */ |
| 16 | enum gelic_lv1_wl_event { |
| 17 | GELIC_LV1_WL_EVENT_DEVICE_READY = 0x01, /* Eurus ready */ |
| 18 | GELIC_LV1_WL_EVENT_SCAN_COMPLETED = 0x02, /* Scan has completed */ |
| 19 | GELIC_LV1_WL_EVENT_DEAUTH = 0x04, /* Deauthed by the AP */ |
| 20 | GELIC_LV1_WL_EVENT_BEACON_LOST = 0x08, /* Beacon lost detected */ |
| 21 | GELIC_LV1_WL_EVENT_CONNECTED = 0x10, /* Connected to AP */ |
| 22 | GELIC_LV1_WL_EVENT_WPA_CONNECTED = 0x20, /* WPA connection */ |
| 23 | GELIC_LV1_WL_EVENT_WPA_ERROR = 0x40, /* MIC error */ |
| 24 | }; |
| 25 | |
| 26 | /* arguments for GELIC_LV1_POST_WLAN_COMMAND netcontrol */ |
| 27 | enum gelic_eurus_command { |
| 28 | GELIC_EURUS_CMD_ASSOC = 1, /* association start */ |
| 29 | GELIC_EURUS_CMD_DISASSOC = 2, /* disassociate */ |
| 30 | GELIC_EURUS_CMD_START_SCAN = 3, /* scan start */ |
| 31 | GELIC_EURUS_CMD_GET_SCAN = 4, /* get scan result */ |
| 32 | GELIC_EURUS_CMD_SET_COMMON_CFG = 5, /* set common config */ |
| 33 | GELIC_EURUS_CMD_GET_COMMON_CFG = 6, /* set common config */ |
| 34 | GELIC_EURUS_CMD_SET_WEP_CFG = 7, /* set WEP config */ |
| 35 | GELIC_EURUS_CMD_GET_WEP_CFG = 8, /* get WEP config */ |
| 36 | GELIC_EURUS_CMD_SET_WPA_CFG = 9, /* set WPA config */ |
| 37 | GELIC_EURUS_CMD_GET_WPA_CFG = 10, /* get WPA config */ |
| 38 | = 11, /* get RSSI info. */ |
| 39 | GELIC_EURUS_CMD_MAX_INDEX |
| 40 | }; |
| 41 | |
| 42 | /* for GELIC_EURUS_CMD_COMMON_CFG */ |
| 43 | enum gelic_eurus_bss_type { |
| 44 | GELIC_EURUS_BSS_INFRA = 0, |
| 45 | GELIC_EURUS_BSS_ADHOC = 1, /* not supported */ |
| 46 | }; |
| 47 | |
| 48 | enum gelic_eurus_auth_method { |
| 49 | GELIC_EURUS_AUTH_OPEN = 0, /* FIXME: WLAN_AUTH_OPEN */ |
| 50 | GELIC_EURUS_AUTH_SHARED = 1, /* not supported */ |
| 51 | }; |
| 52 | |
| 53 | enum gelic_eurus_opmode { |
| 54 | GELIC_EURUS_OPMODE_11BG = 0, /* 802.11b/g */ |
| 55 | GELIC_EURUS_OPMODE_11B = 1, /* 802.11b only */ |
| 56 | GELIC_EURUS_OPMODE_11G = 2, /* 802.11g only */ |
| 57 | }; |
| 58 | |
| 59 | struct gelic_eurus_common_cfg { |
| 60 | /* all fields are big endian */ |
| 61 | u16 scan_index; |
| 62 | u16 bss_type; /* infra or adhoc */ |
| 63 | u16 auth_method; /* shared key or open */ |
| 64 | u16 op_mode; /* B/G */ |
| 65 | } __packed; |
| 66 | |
| 67 | |
| 68 | /* for GELIC_EURUS_CMD_WEP_CFG */ |
| 69 | enum gelic_eurus_wep_security { |
| 70 | GELIC_EURUS_WEP_SEC_NONE = 0, |
| 71 | GELIC_EURUS_WEP_SEC_40BIT = 1, |
| 72 | GELIC_EURUS_WEP_SEC_104BIT = 2, |
| 73 | }; |
| 74 | |
| 75 | struct gelic_eurus_wep_cfg { |
| 76 | /* all fields are big endian */ |
| 77 | u16 security; |
| 78 | u8 key[4][16]; |
| 79 | } __packed; |
| 80 | |
| 81 | /* for GELIC_EURUS_CMD_WPA_CFG */ |
| 82 | enum gelic_eurus_wpa_security { |
| 83 | GELIC_EURUS_WPA_SEC_NONE = 0x0000, |
| 84 | /* group=TKIP, pairwise=TKIP */ |
| 85 | GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP = 0x0001, |
| 86 | /* group=AES, pairwise=AES */ |
| 87 | GELIC_EURUS_WPA_SEC_WPA_AES_AES = 0x0002, |
| 88 | /* group=TKIP, pairwise=TKIP */ |
| 89 | GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP = 0x0004, |
| 90 | /* group=AES, pairwise=AES */ |
| 91 | GELIC_EURUS_WPA_SEC_WPA2_AES_AES = 0x0008, |
| 92 | /* group=TKIP, pairwise=AES */ |
| 93 | GELIC_EURUS_WPA_SEC_WPA_TKIP_AES = 0x0010, |
| 94 | /* group=TKIP, pairwise=AES */ |
| 95 | GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES = 0x0020, |
| 96 | }; |
| 97 | |
| 98 | enum gelic_eurus_wpa_psk_type { |
| 99 | GELIC_EURUS_WPA_PSK_PASSPHRASE = 0, /* passphrase string */ |
| 100 | GELIC_EURUS_WPA_PSK_BIN = 1, /* 32 bytes binary key */ |
| 101 | }; |
| 102 | |
| 103 | #define GELIC_WL_EURUS_PSK_MAX_LEN 64 |
| 104 | #define WPA_PSK_LEN 32 /* WPA spec says 256bit */ |
| 105 | |
| 106 | struct gelic_eurus_wpa_cfg { |
| 107 | /* all fields are big endian */ |
| 108 | u16 security; |
| 109 | u16 psk_type; /* psk key encoding type */ |
| 110 | u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; /* psk key; hex or passphrase */ |
| 111 | } __packed; |
| 112 | |
| 113 | /* for GELIC_EURUS_CMD_{START,GET}_SCAN */ |
| 114 | enum gelic_eurus_scan_capability { |
| 115 | GELIC_EURUS_SCAN_CAP_ADHOC = 0x0000, |
| 116 | GELIC_EURUS_SCAN_CAP_INFRA = 0x0001, |
| 117 | GELIC_EURUS_SCAN_CAP_MASK = 0x0001, |
| 118 | }; |
| 119 | |
| 120 | enum gelic_eurus_scan_sec_type { |
| 121 | GELIC_EURUS_SCAN_SEC_NONE = 0x0000, |
| 122 | GELIC_EURUS_SCAN_SEC_WEP = 0x0100, |
| 123 | GELIC_EURUS_SCAN_SEC_WPA = 0x0200, |
| 124 | GELIC_EURUS_SCAN_SEC_WPA2 = 0x0400, |
| 125 | GELIC_EURUS_SCAN_SEC_MASK = 0x0f00, |
| 126 | }; |
| 127 | |
| 128 | enum gelic_eurus_scan_sec_wep_type { |
| 129 | GELIC_EURUS_SCAN_SEC_WEP_UNKNOWN = 0x0000, |
| 130 | GELIC_EURUS_SCAN_SEC_WEP_40 = 0x0001, |
| 131 | GELIC_EURUS_SCAN_SEC_WEP_104 = 0x0002, |
| 132 | GELIC_EURUS_SCAN_SEC_WEP_MASK = 0x0003, |
| 133 | }; |
| 134 | |
| 135 | enum gelic_eurus_scan_sec_wpa_type { |
| 136 | GELIC_EURUS_SCAN_SEC_WPA_UNKNOWN = 0x0000, |
| 137 | GELIC_EURUS_SCAN_SEC_WPA_TKIP = 0x0001, |
| 138 | GELIC_EURUS_SCAN_SEC_WPA_AES = 0x0002, |
| 139 | GELIC_EURUS_SCAN_SEC_WPA_MASK = 0x0003, |
| 140 | }; |
| 141 | |
| 142 | /* |
| 143 | * hw BSS information structure returned from GELIC_EURUS_CMD_GET_SCAN |
| 144 | */ |
| 145 | struct gelic_eurus_scan_info { |
| 146 | /* all fields are big endian */ |
| 147 | __be16 size; |
| 148 | __be16 ; /* percentage */ |
| 149 | __be16 channel; /* channel number */ |
| 150 | __be16 beacon_period; /* FIXME: in msec unit */ |
| 151 | __be16 capability; |
| 152 | __be16 security; |
| 153 | u8 bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */ |
| 154 | u8 essid[32]; /* IW_ESSID_MAX_SIZE */ |
| 155 | u8 rate[16]; /* first 12 are valid */ |
| 156 | u8 ext_rate[16]; /* first 16 are valid */ |
| 157 | __be32 reserved1; |
| 158 | __be32 reserved2; |
| 159 | __be32 reserved3; |
| 160 | __be32 reserved4; |
| 161 | u8 elements[]; /* ie */ |
| 162 | } __packed; |
| 163 | |
| 164 | /* the hypervisor returns bbs up to 16 */ |
| 165 | #define GELIC_EURUS_MAX_SCAN (16) |
| 166 | struct gelic_wl_scan_info { |
| 167 | struct list_head list; |
| 168 | struct gelic_eurus_scan_info *hwinfo; |
| 169 | |
| 170 | int valid; /* set 1 if this entry was in latest scanned list |
| 171 | * from Eurus */ |
| 172 | unsigned int eurus_index; /* index in the Eurus list */ |
| 173 | unsigned long last_scanned; /* acquired time */ |
| 174 | |
| 175 | unsigned int rate_len; |
| 176 | unsigned int rate_ext_len; |
| 177 | unsigned int essid_len; |
| 178 | }; |
| 179 | |
| 180 | /* for GELIC_EURUS_CMD_GET_RSSI */ |
| 181 | struct { |
| 182 | /* big endian */ |
| 183 | __be16 ; |
| 184 | } __packed; |
| 185 | |
| 186 | |
| 187 | /* for 'stat' member of gelic_wl_info */ |
| 188 | enum gelic_wl_info_status_bit { |
| 189 | GELIC_WL_STAT_CONFIGURED, |
| 190 | GELIC_WL_STAT_CH_INFO, /* ch info acquired */ |
| 191 | GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */ |
| 192 | GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */ |
| 193 | GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */ |
| 194 | GELIC_WL_STAT_WPA_LEVEL_SET, /* WEP or WPA[2] selected */ |
| 195 | }; |
| 196 | |
| 197 | /* for 'scan_stat' member of gelic_wl_info */ |
| 198 | enum gelic_wl_scan_state { |
| 199 | /* just initialized or get last scan result failed */ |
| 200 | GELIC_WL_SCAN_STAT_INIT, |
| 201 | /* scan request issued, accepted or chip is scanning */ |
| 202 | GELIC_WL_SCAN_STAT_SCANNING, |
| 203 | /* scan results retrieved */ |
| 204 | GELIC_WL_SCAN_STAT_GOT_LIST, |
| 205 | }; |
| 206 | |
| 207 | /* for 'cipher_method' */ |
| 208 | enum gelic_wl_cipher_method { |
| 209 | GELIC_WL_CIPHER_NONE, |
| 210 | GELIC_WL_CIPHER_WEP, |
| 211 | GELIC_WL_CIPHER_TKIP, |
| 212 | GELIC_WL_CIPHER_AES, |
| 213 | }; |
| 214 | |
| 215 | /* for 'wpa_level' */ |
| 216 | enum gelic_wl_wpa_level { |
| 217 | GELIC_WL_WPA_LEVEL_NONE, |
| 218 | GELIC_WL_WPA_LEVEL_WPA, |
| 219 | GELIC_WL_WPA_LEVEL_WPA2, |
| 220 | }; |
| 221 | |
| 222 | /* for 'assoc_stat' */ |
| 223 | enum gelic_wl_assoc_state { |
| 224 | GELIC_WL_ASSOC_STAT_DISCONN, |
| 225 | GELIC_WL_ASSOC_STAT_ASSOCIATING, |
| 226 | GELIC_WL_ASSOC_STAT_ASSOCIATED, |
| 227 | }; |
| 228 | /* part of private data alloc_etherdev() allocated */ |
| 229 | #define GELIC_WEP_KEYS 4 |
| 230 | struct gelic_wl_info { |
| 231 | /* bss list */ |
| 232 | struct mutex scan_lock; |
| 233 | struct list_head network_list; |
| 234 | struct list_head network_free_list; |
| 235 | struct gelic_wl_scan_info *networks; |
| 236 | |
| 237 | unsigned long scan_age; /* last scanned time */ |
| 238 | enum gelic_wl_scan_state scan_stat; |
| 239 | struct completion scan_done; |
| 240 | |
| 241 | /* eurus command queue */ |
| 242 | struct workqueue_struct *eurus_cmd_queue; |
| 243 | struct completion cmd_done_intr; |
| 244 | |
| 245 | /* eurus event handling */ |
| 246 | struct workqueue_struct *event_queue; |
| 247 | struct delayed_work event_work; |
| 248 | |
| 249 | /* wl status bits */ |
| 250 | unsigned long stat; |
| 251 | enum gelic_eurus_auth_method auth_method; /* open/shared */ |
| 252 | enum gelic_wl_cipher_method group_cipher_method; |
| 253 | enum gelic_wl_cipher_method pairwise_cipher_method; |
| 254 | enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */ |
| 255 | |
| 256 | /* association handling */ |
| 257 | struct mutex assoc_stat_lock; |
| 258 | struct delayed_work assoc_work; |
| 259 | enum gelic_wl_assoc_state assoc_stat; |
| 260 | struct completion assoc_done; |
| 261 | |
| 262 | spinlock_t lock; |
| 263 | u16 ch_info; /* available channels. bit0 = ch1 */ |
| 264 | /* WEP keys */ |
| 265 | u8 key[GELIC_WEP_KEYS][IW_ENCODING_TOKEN_MAX]; |
| 266 | unsigned long key_enabled; |
| 267 | unsigned int key_len[GELIC_WEP_KEYS]; |
| 268 | unsigned int current_key; |
| 269 | /* WWPA PSK */ |
| 270 | u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; |
| 271 | enum gelic_eurus_wpa_psk_type psk_type; |
| 272 | unsigned int psk_len; |
| 273 | |
| 274 | u8 essid[IW_ESSID_MAX_SIZE]; |
| 275 | u8 bssid[ETH_ALEN]; /* userland requested */ |
| 276 | u8 active_bssid[ETH_ALEN]; /* associated bssid */ |
| 277 | unsigned int essid_len; |
| 278 | |
| 279 | struct iw_statistics iwstat; |
| 280 | }; |
| 281 | |
| 282 | #define GELIC_WL_BSS_MAX_ENT 32 |
| 283 | #define GELIC_WL_ASSOC_RETRY 50 |
| 284 | static inline struct gelic_port *wl_port(struct gelic_wl_info *wl) |
| 285 | { |
| 286 | return container_of((void *)wl, struct gelic_port, priv); |
| 287 | } |
| 288 | static inline struct gelic_wl_info *port_wl(struct gelic_port *port) |
| 289 | { |
| 290 | return port_priv(port); |
| 291 | } |
| 292 | |
| 293 | struct gelic_eurus_cmd { |
| 294 | struct work_struct work; |
| 295 | struct gelic_wl_info *wl; |
| 296 | unsigned int cmd; /* command code */ |
| 297 | u64 tag; |
| 298 | u64 size; |
| 299 | void *buffer; |
| 300 | unsigned int buf_size; |
| 301 | struct completion done; |
| 302 | int status; |
| 303 | u64 cmd_status; |
| 304 | }; |
| 305 | |
| 306 | /* private ioctls to pass PSK */ |
| 307 | #define GELIC_WL_PRIV_SET_PSK (SIOCIWFIRSTPRIV + 0) |
| 308 | #define GELIC_WL_PRIV_GET_PSK (SIOCIWFIRSTPRIV + 1) |
| 309 | |
| 310 | int gelic_wl_driver_probe(struct gelic_card *card); |
| 311 | int gelic_wl_driver_remove(struct gelic_card *card); |
| 312 | void gelic_wl_interrupt(struct net_device *netdev, u64 status); |
| 313 | #endif /* _GELIC_WIRELESS_H */ |
| 314 | |