138e1884dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
28df158acSJeff Kirsher /*
38df158acSJeff Kirsher * PS3 gelic network driver.
48df158acSJeff Kirsher *
58df158acSJeff Kirsher * Copyright (C) 2007 Sony Computer Entertainment Inc.
68df158acSJeff Kirsher * Copyright 2007 Sony Corporation
78df158acSJeff Kirsher */
88df158acSJeff Kirsher #ifndef _GELIC_WIRELESS_H
98df158acSJeff Kirsher #define _GELIC_WIRELESS_H
108df158acSJeff Kirsher
118df158acSJeff Kirsher #include <linux/wireless.h>
128df158acSJeff Kirsher #include <net/iw_handler.h>
138df158acSJeff Kirsher
148df158acSJeff Kirsher
158df158acSJeff Kirsher /* return value from GELIC_LV1_GET_WLAN_EVENT netcontrol */
168df158acSJeff Kirsher enum gelic_lv1_wl_event {
178df158acSJeff Kirsher GELIC_LV1_WL_EVENT_DEVICE_READY = 0x01, /* Eurus ready */
188df158acSJeff Kirsher GELIC_LV1_WL_EVENT_SCAN_COMPLETED = 0x02, /* Scan has completed */
198df158acSJeff Kirsher GELIC_LV1_WL_EVENT_DEAUTH = 0x04, /* Deauthed by the AP */
208df158acSJeff Kirsher GELIC_LV1_WL_EVENT_BEACON_LOST = 0x08, /* Beacon lost detected */
218df158acSJeff Kirsher GELIC_LV1_WL_EVENT_CONNECTED = 0x10, /* Connected to AP */
228df158acSJeff Kirsher GELIC_LV1_WL_EVENT_WPA_CONNECTED = 0x20, /* WPA connection */
238df158acSJeff Kirsher GELIC_LV1_WL_EVENT_WPA_ERROR = 0x40, /* MIC error */
248df158acSJeff Kirsher };
258df158acSJeff Kirsher
268df158acSJeff Kirsher /* arguments for GELIC_LV1_POST_WLAN_COMMAND netcontrol */
278df158acSJeff Kirsher enum gelic_eurus_command {
288df158acSJeff Kirsher GELIC_EURUS_CMD_ASSOC = 1, /* association start */
298df158acSJeff Kirsher GELIC_EURUS_CMD_DISASSOC = 2, /* disassociate */
308df158acSJeff Kirsher GELIC_EURUS_CMD_START_SCAN = 3, /* scan start */
318df158acSJeff Kirsher GELIC_EURUS_CMD_GET_SCAN = 4, /* get scan result */
328df158acSJeff Kirsher GELIC_EURUS_CMD_SET_COMMON_CFG = 5, /* set common config */
338df158acSJeff Kirsher GELIC_EURUS_CMD_GET_COMMON_CFG = 6, /* set common config */
348df158acSJeff Kirsher GELIC_EURUS_CMD_SET_WEP_CFG = 7, /* set WEP config */
358df158acSJeff Kirsher GELIC_EURUS_CMD_GET_WEP_CFG = 8, /* get WEP config */
368df158acSJeff Kirsher GELIC_EURUS_CMD_SET_WPA_CFG = 9, /* set WPA config */
378df158acSJeff Kirsher GELIC_EURUS_CMD_GET_WPA_CFG = 10, /* get WPA config */
388df158acSJeff Kirsher GELIC_EURUS_CMD_GET_RSSI_CFG = 11, /* get RSSI info. */
398df158acSJeff Kirsher GELIC_EURUS_CMD_MAX_INDEX
408df158acSJeff Kirsher };
418df158acSJeff Kirsher
428df158acSJeff Kirsher /* for GELIC_EURUS_CMD_COMMON_CFG */
438df158acSJeff Kirsher enum gelic_eurus_bss_type {
448df158acSJeff Kirsher GELIC_EURUS_BSS_INFRA = 0,
458df158acSJeff Kirsher GELIC_EURUS_BSS_ADHOC = 1, /* not supported */
468df158acSJeff Kirsher };
478df158acSJeff Kirsher
488df158acSJeff Kirsher enum gelic_eurus_auth_method {
498df158acSJeff Kirsher GELIC_EURUS_AUTH_OPEN = 0, /* FIXME: WLAN_AUTH_OPEN */
508df158acSJeff Kirsher GELIC_EURUS_AUTH_SHARED = 1, /* not supported */
518df158acSJeff Kirsher };
528df158acSJeff Kirsher
538df158acSJeff Kirsher enum gelic_eurus_opmode {
548df158acSJeff Kirsher GELIC_EURUS_OPMODE_11BG = 0, /* 802.11b/g */
558df158acSJeff Kirsher GELIC_EURUS_OPMODE_11B = 1, /* 802.11b only */
568df158acSJeff Kirsher GELIC_EURUS_OPMODE_11G = 2, /* 802.11g only */
578df158acSJeff Kirsher };
588df158acSJeff Kirsher
598df158acSJeff Kirsher struct gelic_eurus_common_cfg {
608df158acSJeff Kirsher /* all fields are big endian */
618df158acSJeff Kirsher u16 scan_index;
628df158acSJeff Kirsher u16 bss_type; /* infra or adhoc */
638df158acSJeff Kirsher u16 auth_method; /* shared key or open */
648df158acSJeff Kirsher u16 op_mode; /* B/G */
658df158acSJeff Kirsher } __packed;
668df158acSJeff Kirsher
678df158acSJeff Kirsher
688df158acSJeff Kirsher /* for GELIC_EURUS_CMD_WEP_CFG */
698df158acSJeff Kirsher enum gelic_eurus_wep_security {
708df158acSJeff Kirsher GELIC_EURUS_WEP_SEC_NONE = 0,
718df158acSJeff Kirsher GELIC_EURUS_WEP_SEC_40BIT = 1,
728df158acSJeff Kirsher GELIC_EURUS_WEP_SEC_104BIT = 2,
738df158acSJeff Kirsher };
748df158acSJeff Kirsher
758df158acSJeff Kirsher struct gelic_eurus_wep_cfg {
768df158acSJeff Kirsher /* all fields are big endian */
778df158acSJeff Kirsher u16 security;
788df158acSJeff Kirsher u8 key[4][16];
798df158acSJeff Kirsher } __packed;
808df158acSJeff Kirsher
818df158acSJeff Kirsher /* for GELIC_EURUS_CMD_WPA_CFG */
828df158acSJeff Kirsher enum gelic_eurus_wpa_security {
838df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_NONE = 0x0000,
848df158acSJeff Kirsher /* group=TKIP, pairwise=TKIP */
858df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP = 0x0001,
868df158acSJeff Kirsher /* group=AES, pairwise=AES */
878df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA_AES_AES = 0x0002,
888df158acSJeff Kirsher /* group=TKIP, pairwise=TKIP */
898df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP = 0x0004,
908df158acSJeff Kirsher /* group=AES, pairwise=AES */
918df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA2_AES_AES = 0x0008,
928df158acSJeff Kirsher /* group=TKIP, pairwise=AES */
938df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA_TKIP_AES = 0x0010,
948df158acSJeff Kirsher /* group=TKIP, pairwise=AES */
958df158acSJeff Kirsher GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES = 0x0020,
968df158acSJeff Kirsher };
978df158acSJeff Kirsher
988df158acSJeff Kirsher enum gelic_eurus_wpa_psk_type {
998df158acSJeff Kirsher GELIC_EURUS_WPA_PSK_PASSPHRASE = 0, /* passphrase string */
1008df158acSJeff Kirsher GELIC_EURUS_WPA_PSK_BIN = 1, /* 32 bytes binary key */
1018df158acSJeff Kirsher };
1028df158acSJeff Kirsher
1038df158acSJeff Kirsher #define GELIC_WL_EURUS_PSK_MAX_LEN 64
1048df158acSJeff Kirsher #define WPA_PSK_LEN 32 /* WPA spec says 256bit */
1058df158acSJeff Kirsher
1068df158acSJeff Kirsher struct gelic_eurus_wpa_cfg {
1078df158acSJeff Kirsher /* all fields are big endian */
1088df158acSJeff Kirsher u16 security;
1098df158acSJeff Kirsher u16 psk_type; /* psk key encoding type */
1108df158acSJeff Kirsher u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; /* psk key; hex or passphrase */
1118df158acSJeff Kirsher } __packed;
1128df158acSJeff Kirsher
1138df158acSJeff Kirsher /* for GELIC_EURUS_CMD_{START,GET}_SCAN */
1148df158acSJeff Kirsher enum gelic_eurus_scan_capability {
1158df158acSJeff Kirsher GELIC_EURUS_SCAN_CAP_ADHOC = 0x0000,
1168df158acSJeff Kirsher GELIC_EURUS_SCAN_CAP_INFRA = 0x0001,
1178df158acSJeff Kirsher GELIC_EURUS_SCAN_CAP_MASK = 0x0001,
1188df158acSJeff Kirsher };
1198df158acSJeff Kirsher
1208df158acSJeff Kirsher enum gelic_eurus_scan_sec_type {
1218df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_NONE = 0x0000,
1228df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WEP = 0x0100,
1238df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA = 0x0200,
1248df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA2 = 0x0400,
1258df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_MASK = 0x0f00,
1268df158acSJeff Kirsher };
1278df158acSJeff Kirsher
1288df158acSJeff Kirsher enum gelic_eurus_scan_sec_wep_type {
1298df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WEP_UNKNOWN = 0x0000,
1308df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WEP_40 = 0x0001,
1318df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WEP_104 = 0x0002,
1328df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WEP_MASK = 0x0003,
1338df158acSJeff Kirsher };
1348df158acSJeff Kirsher
1358df158acSJeff Kirsher enum gelic_eurus_scan_sec_wpa_type {
1368df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA_UNKNOWN = 0x0000,
1378df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA_TKIP = 0x0001,
1388df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA_AES = 0x0002,
1398df158acSJeff Kirsher GELIC_EURUS_SCAN_SEC_WPA_MASK = 0x0003,
1408df158acSJeff Kirsher };
1418df158acSJeff Kirsher
1428df158acSJeff Kirsher /*
1438df158acSJeff Kirsher * hw BSS information structure returned from GELIC_EURUS_CMD_GET_SCAN
1448df158acSJeff Kirsher */
1458df158acSJeff Kirsher struct gelic_eurus_scan_info {
1468df158acSJeff Kirsher /* all fields are big endian */
1478df158acSJeff Kirsher __be16 size;
1488df158acSJeff Kirsher __be16 rssi; /* percentage */
1498df158acSJeff Kirsher __be16 channel; /* channel number */
1508df158acSJeff Kirsher __be16 beacon_period; /* FIXME: in msec unit */
1518df158acSJeff Kirsher __be16 capability;
1528df158acSJeff Kirsher __be16 security;
1538df158acSJeff Kirsher u8 bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */
1548df158acSJeff Kirsher u8 essid[32]; /* IW_ESSID_MAX_SIZE */
1558df158acSJeff Kirsher u8 rate[16]; /* first 12 are valid */
1568df158acSJeff Kirsher u8 ext_rate[16]; /* first 16 are valid */
1578df158acSJeff Kirsher __be32 reserved1;
1588df158acSJeff Kirsher __be32 reserved2;
1598df158acSJeff Kirsher __be32 reserved3;
1608df158acSJeff Kirsher __be32 reserved4;
161*f49b2759SGustavo A. R. Silva u8 elements[]; /* ie */
1628df158acSJeff Kirsher } __packed;
1638df158acSJeff Kirsher
1648df158acSJeff Kirsher /* the hypervisor returns bbs up to 16 */
1658df158acSJeff Kirsher #define GELIC_EURUS_MAX_SCAN (16)
1668df158acSJeff Kirsher struct gelic_wl_scan_info {
1678df158acSJeff Kirsher struct list_head list;
1688df158acSJeff Kirsher struct gelic_eurus_scan_info *hwinfo;
1698df158acSJeff Kirsher
1708df158acSJeff Kirsher int valid; /* set 1 if this entry was in latest scanned list
1718df158acSJeff Kirsher * from Eurus */
1728df158acSJeff Kirsher unsigned int eurus_index; /* index in the Eurus list */
1738df158acSJeff Kirsher unsigned long last_scanned; /* acquired time */
1748df158acSJeff Kirsher
1758df158acSJeff Kirsher unsigned int rate_len;
1768df158acSJeff Kirsher unsigned int rate_ext_len;
1778df158acSJeff Kirsher unsigned int essid_len;
1788df158acSJeff Kirsher };
1798df158acSJeff Kirsher
1808df158acSJeff Kirsher /* for GELIC_EURUS_CMD_GET_RSSI */
1818df158acSJeff Kirsher struct gelic_eurus_rssi_info {
1828df158acSJeff Kirsher /* big endian */
1838df158acSJeff Kirsher __be16 rssi;
1848df158acSJeff Kirsher } __packed;
1858df158acSJeff Kirsher
1868df158acSJeff Kirsher
1878df158acSJeff Kirsher /* for 'stat' member of gelic_wl_info */
1888df158acSJeff Kirsher enum gelic_wl_info_status_bit {
1898df158acSJeff Kirsher GELIC_WL_STAT_CONFIGURED,
1908df158acSJeff Kirsher GELIC_WL_STAT_CH_INFO, /* ch info acquired */
1918df158acSJeff Kirsher GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */
1928df158acSJeff Kirsher GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */
1938df158acSJeff Kirsher GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */
1948df158acSJeff Kirsher GELIC_WL_STAT_WPA_LEVEL_SET, /* WEP or WPA[2] selected */
1958df158acSJeff Kirsher };
1968df158acSJeff Kirsher
1978df158acSJeff Kirsher /* for 'scan_stat' member of gelic_wl_info */
1988df158acSJeff Kirsher enum gelic_wl_scan_state {
1998df158acSJeff Kirsher /* just initialized or get last scan result failed */
2008df158acSJeff Kirsher GELIC_WL_SCAN_STAT_INIT,
2018df158acSJeff Kirsher /* scan request issued, accepted or chip is scanning */
2028df158acSJeff Kirsher GELIC_WL_SCAN_STAT_SCANNING,
2038df158acSJeff Kirsher /* scan results retrieved */
2048df158acSJeff Kirsher GELIC_WL_SCAN_STAT_GOT_LIST,
2058df158acSJeff Kirsher };
2068df158acSJeff Kirsher
2078df158acSJeff Kirsher /* for 'cipher_method' */
2088df158acSJeff Kirsher enum gelic_wl_cipher_method {
2098df158acSJeff Kirsher GELIC_WL_CIPHER_NONE,
2108df158acSJeff Kirsher GELIC_WL_CIPHER_WEP,
2118df158acSJeff Kirsher GELIC_WL_CIPHER_TKIP,
2128df158acSJeff Kirsher GELIC_WL_CIPHER_AES,
2138df158acSJeff Kirsher };
2148df158acSJeff Kirsher
2158df158acSJeff Kirsher /* for 'wpa_level' */
2168df158acSJeff Kirsher enum gelic_wl_wpa_level {
2178df158acSJeff Kirsher GELIC_WL_WPA_LEVEL_NONE,
2188df158acSJeff Kirsher GELIC_WL_WPA_LEVEL_WPA,
2198df158acSJeff Kirsher GELIC_WL_WPA_LEVEL_WPA2,
2208df158acSJeff Kirsher };
2218df158acSJeff Kirsher
2228df158acSJeff Kirsher /* for 'assoc_stat' */
2238df158acSJeff Kirsher enum gelic_wl_assoc_state {
2248df158acSJeff Kirsher GELIC_WL_ASSOC_STAT_DISCONN,
2258df158acSJeff Kirsher GELIC_WL_ASSOC_STAT_ASSOCIATING,
2268df158acSJeff Kirsher GELIC_WL_ASSOC_STAT_ASSOCIATED,
2278df158acSJeff Kirsher };
2288df158acSJeff Kirsher /* part of private data alloc_etherdev() allocated */
2298df158acSJeff Kirsher #define GELIC_WEP_KEYS 4
2308df158acSJeff Kirsher struct gelic_wl_info {
2318df158acSJeff Kirsher /* bss list */
2328df158acSJeff Kirsher struct mutex scan_lock;
2338df158acSJeff Kirsher struct list_head network_list;
2348df158acSJeff Kirsher struct list_head network_free_list;
2358df158acSJeff Kirsher struct gelic_wl_scan_info *networks;
2368df158acSJeff Kirsher
2378df158acSJeff Kirsher unsigned long scan_age; /* last scanned time */
2388df158acSJeff Kirsher enum gelic_wl_scan_state scan_stat;
2398df158acSJeff Kirsher struct completion scan_done;
2408df158acSJeff Kirsher
2418df158acSJeff Kirsher /* eurus command queue */
2428df158acSJeff Kirsher struct workqueue_struct *eurus_cmd_queue;
2438df158acSJeff Kirsher struct completion cmd_done_intr;
2448df158acSJeff Kirsher
2458df158acSJeff Kirsher /* eurus event handling */
2468df158acSJeff Kirsher struct workqueue_struct *event_queue;
2478df158acSJeff Kirsher struct delayed_work event_work;
2488df158acSJeff Kirsher
2498df158acSJeff Kirsher /* wl status bits */
2508df158acSJeff Kirsher unsigned long stat;
2518df158acSJeff Kirsher enum gelic_eurus_auth_method auth_method; /* open/shared */
2528df158acSJeff Kirsher enum gelic_wl_cipher_method group_cipher_method;
2538df158acSJeff Kirsher enum gelic_wl_cipher_method pairwise_cipher_method;
2548df158acSJeff Kirsher enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */
2558df158acSJeff Kirsher
2568df158acSJeff Kirsher /* association handling */
2578df158acSJeff Kirsher struct mutex assoc_stat_lock;
2588df158acSJeff Kirsher struct delayed_work assoc_work;
2598df158acSJeff Kirsher enum gelic_wl_assoc_state assoc_stat;
2608df158acSJeff Kirsher struct completion assoc_done;
2618df158acSJeff Kirsher
2628df158acSJeff Kirsher spinlock_t lock;
2638df158acSJeff Kirsher u16 ch_info; /* available channels. bit0 = ch1 */
2648df158acSJeff Kirsher /* WEP keys */
2658df158acSJeff Kirsher u8 key[GELIC_WEP_KEYS][IW_ENCODING_TOKEN_MAX];
2668df158acSJeff Kirsher unsigned long key_enabled;
2678df158acSJeff Kirsher unsigned int key_len[GELIC_WEP_KEYS];
2688df158acSJeff Kirsher unsigned int current_key;
2698df158acSJeff Kirsher /* WWPA PSK */
2708df158acSJeff Kirsher u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN];
2718df158acSJeff Kirsher enum gelic_eurus_wpa_psk_type psk_type;
2728df158acSJeff Kirsher unsigned int psk_len;
2738df158acSJeff Kirsher
2748df158acSJeff Kirsher u8 essid[IW_ESSID_MAX_SIZE];
2758df158acSJeff Kirsher u8 bssid[ETH_ALEN]; /* userland requested */
2768df158acSJeff Kirsher u8 active_bssid[ETH_ALEN]; /* associated bssid */
2778df158acSJeff Kirsher unsigned int essid_len;
2788df158acSJeff Kirsher
2798df158acSJeff Kirsher struct iw_public_data wireless_data;
2808df158acSJeff Kirsher struct iw_statistics iwstat;
2818df158acSJeff Kirsher };
2828df158acSJeff Kirsher
2838df158acSJeff Kirsher #define GELIC_WL_BSS_MAX_ENT 32
2848df158acSJeff Kirsher #define GELIC_WL_ASSOC_RETRY 50
wl_port(struct gelic_wl_info * wl)2858df158acSJeff Kirsher static inline struct gelic_port *wl_port(struct gelic_wl_info *wl)
2868df158acSJeff Kirsher {
2878df158acSJeff Kirsher return container_of((void *)wl, struct gelic_port, priv);
2888df158acSJeff Kirsher }
port_wl(struct gelic_port * port)2898df158acSJeff Kirsher static inline struct gelic_wl_info *port_wl(struct gelic_port *port)
2908df158acSJeff Kirsher {
2918df158acSJeff Kirsher return port_priv(port);
2928df158acSJeff Kirsher }
2938df158acSJeff Kirsher
2948df158acSJeff Kirsher struct gelic_eurus_cmd {
2958df158acSJeff Kirsher struct work_struct work;
2968df158acSJeff Kirsher struct gelic_wl_info *wl;
2978df158acSJeff Kirsher unsigned int cmd; /* command code */
2988df158acSJeff Kirsher u64 tag;
2998df158acSJeff Kirsher u64 size;
3008df158acSJeff Kirsher void *buffer;
3018df158acSJeff Kirsher unsigned int buf_size;
3028df158acSJeff Kirsher struct completion done;
3038df158acSJeff Kirsher int status;
3048df158acSJeff Kirsher u64 cmd_status;
3058df158acSJeff Kirsher };
3068df158acSJeff Kirsher
3078df158acSJeff Kirsher /* private ioctls to pass PSK */
3088df158acSJeff Kirsher #define GELIC_WL_PRIV_SET_PSK (SIOCIWFIRSTPRIV + 0)
3098df158acSJeff Kirsher #define GELIC_WL_PRIV_GET_PSK (SIOCIWFIRSTPRIV + 1)
3108df158acSJeff Kirsher
3113e0dd1f4SJoe Perches int gelic_wl_driver_probe(struct gelic_card *card);
3123e0dd1f4SJoe Perches int gelic_wl_driver_remove(struct gelic_card *card);
3133e0dd1f4SJoe Perches void gelic_wl_interrupt(struct net_device *netdev, u64 status);
3148df158acSJeff Kirsher #endif /* _GELIC_WIRELESS_H */
315