1177595Sweongyo/*- 2177595Sweongyo * Copyright (c) 2007 Marvell Semiconductor, Inc. 3177595Sweongyo * Copyright (c) 2007 Sam Leffler, Errno Consulting 4177595Sweongyo * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org> 5177595Sweongyo * All rights reserved. 6177595Sweongyo * 7177595Sweongyo * Redistribution and use in source and binary forms, with or without 8177595Sweongyo * modification, are permitted provided that the following conditions 9177595Sweongyo * are met: 10177595Sweongyo * 1. Redistributions of source code must retain the above copyright 11177595Sweongyo * notice, this list of conditions and the following disclaimer, 12177595Sweongyo * without modification. 13177595Sweongyo * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14177595Sweongyo * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 15177595Sweongyo * redistribution must be conditioned upon including a substantially 16177595Sweongyo * similar Disclaimer requirement for further binary redistribution. 17177595Sweongyo * 18177595Sweongyo * NO WARRANTY 19177595Sweongyo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20177595Sweongyo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21177595Sweongyo * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 22177595Sweongyo * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23177595Sweongyo * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 24177595Sweongyo * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25177595Sweongyo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26177595Sweongyo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27177595Sweongyo * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28177595Sweongyo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29177595Sweongyo * THE POSSIBILITY OF SUCH DAMAGES. 30177595Sweongyo * 31177595Sweongyo * $FreeBSD$ 32177595Sweongyo */ 33177595Sweongyo 34177595Sweongyo/* 35177595Sweongyo * Definitions for the Marvell 88W8335 Wireless LAN controller. 36177595Sweongyo */ 37177595Sweongyo#ifndef _DEV_MALO_H 38177595Sweongyo#define _DEV_MALO_H 39177595Sweongyo 40177595Sweongyo#include <net80211/ieee80211_radiotap.h> 41177595Sweongyo#include <dev/malo/if_malohal.h> 42177595Sweongyo#include <dev/malo/if_maloioctl.h> 43177595Sweongyo 44177595Sweongyo#ifndef MALO_TXBUF 45177595Sweongyo#define MALO_TXBUF 256 /* number of TX descriptors/buffers */ 46177595Sweongyo#endif 47177595Sweongyo#ifndef MALO_RXBUF 48177595Sweongyo#define MALO_RXBUF 256 /* number of RX descriptors/buffers */ 49177595Sweongyo#endif 50177595Sweongyo 51177595Sweongyo#define MALO_TXDESC 1 /* max tx descriptors/segments */ 52177595Sweongyo 53177595Sweongyo#define MALO_RXSIZE PAGE_SIZE 54177595Sweongyo#define MALO_RSSI_DUMMY_MARKER 127 55177595Sweongyo#define MALO_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ 56177595Sweongyo 57177595Sweongyo#define MALO_REG_INT_CODE 0x00000C14 58177595Sweongyo/* From host to ARM */ 59177595Sweongyo#define MALO_REG_H2A_INTERRUPT_EVENTS 0x00000C18 60177595Sweongyo 61177595Sweongyo/* bit definitions for MALO_REG_H2A_INTERRUPT_CAUSE */ 62177595Sweongyo#define MALO_H2ARIC_BIT_PPA_READY 0x00000001 63177595Sweongyo#define MALO_H2ARIC_BIT_DOOR_BELL 0x00000002 /* bit 1 */ 64177595Sweongyo#define MALO_H2ARIC_BIT_PS 0x00000004 65177595Sweongyo#define MALO_H2ARIC_BIT_PSPOLL 0x00000008 /* bit 3 */ 66177595Sweongyo 67177595Sweongyo/* From ARM to host */ 68177595Sweongyo#define MALO_REG_A2H_INTERRUPT_CAUSE 0x00000C30 69177595Sweongyo#define MALO_REG_A2H_INTERRUPT_MASK 0x00000C34 70177595Sweongyo#define MALO_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 71177595Sweongyo#define MALO_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C 72177595Sweongyo 73177595Sweongyo/* bit definitions for MALO_REG_A2H_INTERRUPT_CAUSE */ 74177595Sweongyo#define MALO_A2HRIC_BIT_TX_DONE 0x00000001 /* bit 0 */ 75177595Sweongyo#define MALO_A2HRIC_BIT_RX_RDY 0x00000002 /* bit 1 */ 76177595Sweongyo#define MALO_A2HRIC_BIT_OPC_DONE 0x00000004 77177595Sweongyo#define MALO_A2HRIC_BIT_MAC_EVENT 0x00000008 78177595Sweongyo#define MALO_A2HRIC_BIT_RX_PROBLEM 0x00000010 79177595Sweongyo#define MALO_A2HRIC_BIT_RADIO_OFF 0x00000020 /* bit 5 */ 80177595Sweongyo#define MALO_A2HRIC_BIT_RADIO_ON 0x00000040 81177595Sweongyo#define MALO_A2HRIC_BIT_RADAR_DETECT 0x00000080 82177595Sweongyo#define MALO_A2HRIC_BIT_ICV_ERROR 0x00000100 83177595Sweongyo#define MALO_A2HRIC_BIT_MIC_ERROR 0x00000200 /* bit 9 */ 84177595Sweongyo#define MALO_A2HRIC_BIT_QUEUE_EMPTY 0x00000400 85177595Sweongyo#define MALO_A2HRIC_BIT_QUEUE_FULL 0x00000800 86177595Sweongyo#define MALO_A2HRIC_BIT_CHAN_SWITCH 0x00001000 87177595Sweongyo#define MALO_A2HRIC_BIT_TX_WATCHDOG 0x00002000 88177595Sweongyo#define MALO_A2HRIC_BIT_BA_WATCHDOG 0x00004000 89177595Sweongyo 90177595Sweongyo#define MALO_ISR_SRC_BITS \ 91177595Sweongyo (MALO_A2HRIC_BIT_RX_RDY | \ 92177595Sweongyo MALO_A2HRIC_BIT_TX_DONE | \ 93177595Sweongyo MALO_A2HRIC_BIT_OPC_DONE | \ 94177595Sweongyo MALO_A2HRIC_BIT_MAC_EVENT | \ 95177595Sweongyo MALO_A2HRIC_BIT_MIC_ERROR | \ 96177595Sweongyo MALO_A2HRIC_BIT_ICV_ERROR | \ 97177595Sweongyo MALO_A2HRIC_BIT_RADAR_DETECT | \ 98177595Sweongyo MALO_A2HRIC_BIT_CHAN_SWITCH | \ 99177595Sweongyo MALO_A2HRIC_BIT_TX_WATCHDOG | \ 100177595Sweongyo MALO_A2HRIC_BIT_QUEUE_EMPTY) 101177595Sweongyo#define MALO_ISR_RESET (1<<15) 102177595Sweongyo 103177595Sweongyo#define MALO_A2HRIC_BIT_MASK MALO_ISR_SRC_BITS 104177595Sweongyo 105177595Sweongyo/* map to 0x80000000 on BAR1 */ 106177595Sweongyo#define MALO_REG_GEN_PTR 0x00000C10 107177595Sweongyo#define MALO_REG_INT_CODE 0x00000C14 108177595Sweongyo#define MALO_REG_SCRATCH 0x00000C40 109177595Sweongyo 110177595Sweongyo/* 111177595Sweongyo * define OpMode for SoftAP/Station mode 112177595Sweongyo * 113177595Sweongyo * the following mode signature has to be written to PCI scratch register#0 114177595Sweongyo * right after successfully downloading the last block of firmware and 115177595Sweongyo * before waiting for firmware ready signature 116177595Sweongyo */ 117177595Sweongyo#define MALO_HOSTCMD_STA_MODE 0x5A 118177595Sweongyo#define MALO_HOSTCMD_STA_FWRDY_SIGNATURE 0xF0F1F2F4 119177595Sweongyo 120177595Sweongyo/* 121177595Sweongyo * 16 bit host command code 122177595Sweongyo */ 123177595Sweongyo#define MALO_HOSTCMD_NONE 0x0000 124177595Sweongyo#define MALO_HOSTCMD_CODE_DNLD 0x0001 125177595Sweongyo#define MALO_HOSTCMD_GET_HW_SPEC 0x0003 126177595Sweongyo#define MALO_HOSTCMD_SET_HW_SPEC 0x0004 127177595Sweongyo#define MALO_HOSTCMD_MAC_MULTICAST_ADR 0x0010 128177595Sweongyo#define MALO_HOSTCMD_SET_WEPKEY 0x0013 129177595Sweongyo#define MALO_HOSTCMD_802_11_RADIO_CONTROL 0x001c 130177595Sweongyo#define MALO_HOSTCMD_802_11_RF_TX_POWER 0x001e 131177595Sweongyo#define MALO_HOSTCMD_802_11_RF_ANTENNA 0x0020 132177595Sweongyo#define MALO_HOSTCMD_SET_PRE_SCAN 0x0107 133177595Sweongyo#define MALO_HOSTCMD_SET_POST_SCAN 0x0108 134177595Sweongyo#define MALO_HOSTCMD_SET_RF_CHANNEL 0x010a 135177595Sweongyo#define MALO_HOSTCMD_SET_AID 0x010d 136177595Sweongyo#define MALO_HOSTCMD_SET_RATE 0x0110 137177595Sweongyo#define MALO_HOSTCMD_SET_SLOT 0x0114 138177595Sweongyo/* define DFS lab commands */ 139177595Sweongyo#define MALO_HOSTCMD_SET_FIXED_RATE 0x0126 140177595Sweongyo#define MALO_HOSTCMD_SET_REGION_POWER 0x0128 141177595Sweongyo#define MALO_HOSTCMD_GET_CALTABLE 0x1134 142177595Sweongyo 143177595Sweongyo/* 144177595Sweongyo * definition of action or option for each command. 145177595Sweongyo */ 146177595Sweongyo/* define general purpose action */ 147177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_GET 0x0000 148177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_SET 0x0001 149177595Sweongyo#define MALO_HOSTCMD_ACT_GEN_SET_LIST 0x0002 150177595Sweongyo 151177595Sweongyo/* define action or option for HostCmd_FW_USE_FIXED_RATE */ 152177595Sweongyo#define MALO_HOSTCMD_ACT_USE_FIXED_RATE 0x0001 153177595Sweongyo#define MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE 0x0002 154177595Sweongyo 155177595Sweongyo/* INT code register event definition */ 156177595Sweongyo#define MALO_INT_CODE_CMD_FINISHED 0x00000005 157177595Sweongyo 158177595Sweongyostruct malo_cmd_header { 159177595Sweongyo uint16_t cmd; 160177595Sweongyo uint16_t length; 161177595Sweongyo uint16_t seqnum; 162177595Sweongyo uint16_t result; 163177595Sweongyo} __packed; 164177595Sweongyo 165177595Sweongyostruct malo_cmd_caltable { 166177595Sweongyo struct malo_cmd_header cmdhdr; 167177595Sweongyo uint8_t annex; 168177595Sweongyo uint8_t index; 169177595Sweongyo uint8_t len; 170177595Sweongyo uint8_t reserverd; 171177595Sweongyo#define MALO_CAL_TBL_SIZE 160 172177595Sweongyo uint8_t caltbl[MALO_CAL_TBL_SIZE]; 173177595Sweongyo} __packed; 174177595Sweongyo 175177595Sweongyostruct malo_cmd_get_hwspec { 176177595Sweongyo struct malo_cmd_header cmdhdr; 177177595Sweongyo u_int8_t version; /* version of the HW */ 178177595Sweongyo u_int8_t hostif; /* host interface */ 179177595Sweongyo /* Max. number of WCB FW can handle */ 180177595Sweongyo u_int16_t num_wcb; 181177595Sweongyo /* MaxNbr of MC addresses FW can handle */ 182177595Sweongyo u_int16_t num_mcastaddr; 183177595Sweongyo /* MAC address programmed in HW */ 184177595Sweongyo u_int8_t permaddr[6]; 185177595Sweongyo u_int16_t regioncode; 186177595Sweongyo /* Number of antenna used */ 187177595Sweongyo u_int16_t num_antenna; 188177595Sweongyo /* 4 byte of FW release number */ 189177595Sweongyo u_int32_t fw_releasenum; 190177595Sweongyo u_int32_t wcbbase0; 191177595Sweongyo u_int32_t rxpdwr_ptr; 192177595Sweongyo u_int32_t rxpdrd_ptr; 193177595Sweongyo u_int32_t ul_fw_awakecookie; 194177595Sweongyo u_int32_t wcbbase1; 195177595Sweongyo u_int32_t wcbbase2; 196177595Sweongyo u_int32_t wcbbase3; 197177595Sweongyo} __packed; 198177595Sweongyo 199177595Sweongyostruct malo_cmd_set_hwspec { 200177595Sweongyo struct malo_cmd_header cmdhdr; 201177595Sweongyo uint8_t version; /* HW revision */ 202177595Sweongyo uint8_t hostif; /* Host interface */ 203177595Sweongyo /* Max. number of Multicast address FW can handle */ 204177595Sweongyo uint16_t num_mcastaddr; 205177595Sweongyo uint8_t permaddr[6]; /* MAC address */ 206177595Sweongyo uint16_t regioncode; /* Region Code */ 207177595Sweongyo /* 4 byte of FW release number */ 208177595Sweongyo uint32_t fwreleasenum; 209177595Sweongyo /* Firmware awake cookie */ 210177595Sweongyo uint32_t ul_fw_awakecookie; 211177595Sweongyo /* Device capabilities (see above) */ 212177595Sweongyo uint32_t devicecaps; 213177595Sweongyo uint32_t rxpdwrptr; /* Rx shared memory queue */ 214177595Sweongyo /* # TX queues in WcbBase array */ 215177595Sweongyo uint32_t num_txqueues; 216177595Sweongyo /* TX WCB Rings */ 217177595Sweongyo uint32_t wcbbase[MALO_MAX_TXWCB_QUEUES]; 218177595Sweongyo uint32_t flags; 219177595Sweongyo uint32_t txwcbnum_per_queue; 220177595Sweongyo uint32_t total_rxwcb; 221177595Sweongyo} __packed; 222177595Sweongyo 223177595Sweongyo/* DS 802.11 */ 224177595Sweongyostruct malo_cmd_rf_antenna { 225177595Sweongyo struct malo_cmd_header cmdhdr; 226177595Sweongyo uint16_t action; 227177595Sweongyo /* Number of antennas or 0xffff (diversity) */ 228177595Sweongyo uint16_t mode; 229177595Sweongyo} __packed; 230177595Sweongyo 231177595Sweongyostruct malo_cmd_radio_control { 232177595Sweongyo struct malo_cmd_header cmdhdr; 233177595Sweongyo uint16_t action; 234177595Sweongyo /* 235177595Sweongyo * bit 0 : 1 = on, 0 = off 236177595Sweongyo * bit 1 : 1 = long, 0 = short 237177595Sweongyo * bit 2 : 1 = auto, 0 = fix 238177595Sweongyo */ 239177595Sweongyo uint16_t control; 240177595Sweongyo uint16_t radio_on; 241177595Sweongyo} __packed; 242177595Sweongyo 243177595Sweongyostruct malo_cmd_fw_set_wmmmode { 244177595Sweongyo struct malo_cmd_header cmdhdr; 245177595Sweongyo uint16_t action; /* 0 -> unset, 1 -> set */ 246177595Sweongyo} __packed; 247177595Sweongyo 248177595Sweongyostruct malo_cmd_fw_set_rf_channel { 249177595Sweongyo struct malo_cmd_header cmdhdr; 250177595Sweongyo uint16_t action; 251177595Sweongyo uint8_t cur_channel; /* channel # */ 252177595Sweongyo} __packed; 253177595Sweongyo 254177595Sweongyo#define MALO_TX_POWER_LEVEL_TOTAL 8 255177595Sweongyostruct malo_cmd_rf_tx_power { 256177595Sweongyo struct malo_cmd_header cmdhdr; 257177595Sweongyo uint16_t action; 258177595Sweongyo uint16_t support_txpower_level; 259177595Sweongyo uint16_t current_txpower_level; 260177595Sweongyo uint16_t reserved; 261177595Sweongyo uint16_t power_levellist[MALO_TX_POWER_LEVEL_TOTAL]; 262177595Sweongyo} __packed; 263177595Sweongyo 264177595Sweongyostruct malo_fixrate_flag { 265177595Sweongyo /* lower rate after the retry count. 0 = legacy, 1 = HT */ 266177595Sweongyo uint32_t type; 267177595Sweongyo /* 0: retry count is not valid, 1: use retry count specified */ 268177595Sweongyo uint32_t retrycount_valid; 269177595Sweongyo} __packed; 270177595Sweongyo 271177595Sweongyostruct malo_fixed_rate_entry { 272177595Sweongyo struct malo_fixrate_flag typeflags; 273177595Sweongyo /* legacy rate(not index) or an MCS code. */ 274177595Sweongyo uint32_t fixedrate; 275177595Sweongyo uint32_t retrycount; 276177595Sweongyo} __packed; 277177595Sweongyo 278177595Sweongyostruct malo_cmd_fw_use_fixed_rate { 279177595Sweongyo struct malo_cmd_header cmdhdr; 280177595Sweongyo /* 281177595Sweongyo * MALO_HOSTCMD_ACT_GEN_GET 0x0000 282177595Sweongyo * MALO_HOSTCMD_ACT_GEN_SET 0x0001 283177595Sweongyo * MALO_HOSTCMD_ACT_NOT_USE_FIXED_RATE 0x0002 284177595Sweongyo */ 285177595Sweongyo uint32_t action; 286177595Sweongyo /* use fixed rate specified but firmware can drop to */ 287177595Sweongyo uint32_t allowratedrop; 288177595Sweongyo uint32_t entrycount; 289177595Sweongyo struct malo_fixed_rate_entry fixedrate_table[4]; 290177595Sweongyo uint8_t multicast_rate; 291177595Sweongyo uint8_t multirate_txtype; 292177595Sweongyo uint8_t management_rate; 293177595Sweongyo} __packed; 294177595Sweongyo 295177595Sweongyo#define MALO_RATE_INDEX_MAX_ARRAY 14 296177595Sweongyo 297177595Sweongyostruct malo_cmd_fw_set_aid { 298177595Sweongyo struct malo_cmd_header cmdhdr; 299177595Sweongyo uint16_t associd; 300177595Sweongyo uint8_t macaddr[6]; /* AP's Mac Address(BSSID) */ 301177595Sweongyo uint32_t gprotection; 302177595Sweongyo uint8_t aprates[MALO_RATE_INDEX_MAX_ARRAY]; 303177595Sweongyo} __packed; 304177595Sweongyo 305177595Sweongyostruct malo_cmd_prescan { 306177595Sweongyo struct malo_cmd_header cmdhdr; 307177595Sweongyo} __packed; 308177595Sweongyo 309177595Sweongyostruct malo_cmd_postscan { 310177595Sweongyo struct malo_cmd_header cmdhdr; 311177595Sweongyo uint32_t isibss; 312177595Sweongyo uint8_t bssid[6]; 313177595Sweongyo} __packed; 314177595Sweongyo 315177595Sweongyostruct malo_cmd_fw_setslot { 316177595Sweongyo struct malo_cmd_header cmdhdr; 317177595Sweongyo uint16_t action; 318177595Sweongyo /* slot = 0 if regular, slot = 1 if short. */ 319177595Sweongyo uint8_t slot; 320177595Sweongyo}; 321177595Sweongyo 322177595Sweongyostruct malo_cmd_set_rate { 323177595Sweongyo struct malo_cmd_header cmdhdr; 324177595Sweongyo uint8_t dataratetype; 325177595Sweongyo uint8_t rateindex; 326177595Sweongyo uint8_t aprates[14]; 327177595Sweongyo} __packed; 328177595Sweongyo 329177595Sweongyostruct malo_cmd_wepkey { 330177595Sweongyo struct malo_cmd_header cmdhdr; 331177595Sweongyo uint16_t action; 332177595Sweongyo uint8_t len; 333177595Sweongyo uint8_t flags; 334177595Sweongyo uint16_t index; 335177595Sweongyo uint8_t value[IEEE80211_KEYBUF_SIZE]; 336177595Sweongyo uint8_t txmickey[IEEE80211_WEP_MICLEN]; 337177595Sweongyo uint8_t rxmickey[IEEE80211_WEP_MICLEN]; 338177595Sweongyo uint64_t rxseqctr; 339177595Sweongyo uint64_t txseqctr; 340177595Sweongyo} __packed; 341177595Sweongyo 342177595Sweongyostruct malo_cmd_mcast { 343177595Sweongyo struct malo_cmd_header cmdhdr; 344177595Sweongyo uint16_t action; 345177595Sweongyo uint16_t numaddr; 346177595Sweongyo#define MALO_HAL_MCAST_MAX 32 347177595Sweongyo uint8_t maclist[6*32]; 348177595Sweongyo} __packed; 349177595Sweongyo 350177595Sweongyo/* 351177595Sweongyo * DMA state for tx/rx descriptors. 352177595Sweongyo */ 353177595Sweongyo 354177595Sweongyo/* 355177595Sweongyo * Common "base class" for tx/rx descriptor resources 356177595Sweongyo * allocated using the bus dma api. 357177595Sweongyo */ 358177595Sweongyostruct malo_descdma { 359177595Sweongyo const char* dd_name; 360177595Sweongyo void *dd_desc; /* descriptors */ 361177595Sweongyo bus_addr_t dd_desc_paddr; /* physical addr of dd_desc */ 362177595Sweongyo bus_size_t dd_desc_len; /* size of dd_desc */ 363177595Sweongyo bus_dma_segment_t dd_dseg; 364177595Sweongyo int dd_dnseg; /* number of segments */ 365177595Sweongyo bus_dma_tag_t dd_dmat; /* bus DMA tag */ 366177595Sweongyo bus_dmamap_t dd_dmamap; /* DMA map for descriptors */ 367177595Sweongyo void *dd_bufptr; /* associated buffers */ 368177595Sweongyo}; 369177595Sweongyo 370177595Sweongyo/* 371177595Sweongyo * Hardware tx/rx descriptors. 372177595Sweongyo * 373177595Sweongyo * NB: tx descriptor size must match f/w expected size 374177595Sweongyo * because f/w prefetch's the next descriptor linearly 375177595Sweongyo * and doesn't chase the next pointer. 376177595Sweongyo */ 377177595Sweongyostruct malo_txdesc { 378177595Sweongyo uint32_t status; 379177595Sweongyo#define MALO_TXD_STATUS_IDLE 0x00000000 380177595Sweongyo#define MALO_TXD_STATUS_USED 0x00000001 381177595Sweongyo#define MALO_TXD_STATUS_OK 0x00000001 382177595Sweongyo#define MALO_TXD_STATUS_OK_RETRY 0x00000002 383177595Sweongyo#define MALO_TXD_STATUS_OK_MORE_RETRY 0x00000004 384177595Sweongyo#define MALO_TXD_STATUS_MULTICAST_TX 0x00000008 385177595Sweongyo#define MALO_TXD_STATUS_BROADCAST_TX 0x00000010 386177595Sweongyo#define MALO_TXD_STATUS_FAILED_LINK_ERROR 0x00000020 387177595Sweongyo#define MALO_TXD_STATUS_FAILED_EXCEED_LIMIT 0x00000040 388177595Sweongyo#define MALO_TXD_STATUS_FAILED_XRETRY MALO_TXD_STATUS_FAILED_EXCEED_LIMIT 389177595Sweongyo#define MALO_TXD_STATUS_FAILED_AGING 0x00000080 390177595Sweongyo#define MALO_TXD_STATUS_FW_OWNED 0x80000000 391177595Sweongyo uint8_t datarate; 392177595Sweongyo uint8_t txpriority; 393177595Sweongyo uint16_t qosctrl; 394177595Sweongyo uint32_t pktptr; 395177595Sweongyo uint16_t pktlen; 396177595Sweongyo uint8_t destaddr[6]; 397177595Sweongyo uint32_t physnext; 398177595Sweongyo uint32_t sap_pktinfo; 399177595Sweongyo uint16_t format; 400177595Sweongyo#define MALO_TXD_FORMAT 0x0001 /* frame format/rate */ 401177595Sweongyo#define MALO_TXD_FORMAT_LEGACY 0x0000 /* legacy rate frame */ 402177595Sweongyo#define MALO_TXD_RATE 0x01f8 /* tx rate (legacy)/ MCS */ 403177595Sweongyo#define MALO_TXD_RATE_S 3 404177595Sweongyo/* NB: 3 is reserved */ 405177595Sweongyo#define MALO_TXD_ANTENNA 0x1800 /* antenna select */ 406177595Sweongyo#define MALO_TXD_ANTENNA_S 11 407177595Sweongyo uint16_t pad; /* align to 4-byte boundary */ 408177595Sweongyo} __packed; 409177595Sweongyo 410177595Sweongyo#define MALO_TXDESC_SYNC(txq, ds, how) do { \ 411177595Sweongyo bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how); \ 412177595Sweongyo} while(0) 413177595Sweongyo 414177595Sweongyostruct malo_rxdesc { 415177595Sweongyo uint8_t rxcontrol; /* control element */ 416177595Sweongyo#define MALO_RXD_CTRL_DRIVER_OWN 0x00 417177595Sweongyo#define MALO_RXD_CTRL_OS_OWN 0x04 418177595Sweongyo#define MALO_RXD_CTRL_DMA_OWN 0x80 419177595Sweongyo uint8_t snr; /* signal to noise ratio */ 420177595Sweongyo uint8_t status; /* status field w/ USED bit */ 421177595Sweongyo#define MALO_RXD_STATUS_IDLE 0x00 422177595Sweongyo#define MALO_RXD_STATUS_OK 0x01 423177595Sweongyo#define MALO_RXD_STATUS_MULTICAST_RX 0x02 424177595Sweongyo#define MALO_RXD_STATUS_BROADCAST_RX 0x04 425177595Sweongyo#define MALO_RXD_STATUS_FRAGMENT_RX 0x08 426177595Sweongyo#define MALO_RXD_STATUS_GENERAL_DECRYPT_ERR 0xff 427177595Sweongyo#define MALO_RXD_STATUS_DECRYPT_ERR_MASK 0x80 428177595Sweongyo#define MALO_RXD_STATUS_TKIP_MIC_DECRYPT_ERR 0x02 429177595Sweongyo#define MALO_RXD_STATUS_WEP_ICV_DECRYPT_ERR 0x04 430177595Sweongyo#define MALO_RXD_STATUS_TKIP_ICV_DECRYPT_ERR 0x08 431177595Sweongyo uint8_t channel; /* channel # pkt received on */ 432177595Sweongyo uint16_t pktlen; /* total length of received data */ 433177595Sweongyo uint8_t nf; /* noise floor */ 434177595Sweongyo uint8_t rate; /* received data rate */ 435177595Sweongyo uint32_t physbuffdata; /* physical address of payload data */ 436177595Sweongyo uint32_t physnext; /* physical address of next RX desc */ 437177595Sweongyo uint16_t qosctrl; /* received QosCtrl field variable */ 438177595Sweongyo uint16_t htsig2; /* like name states */ 439177595Sweongyo} __packed; 440177595Sweongyo 441177595Sweongyo#define MALO_RXDESC_SYNC(sc, ds, how) do { \ 442177595Sweongyo bus_dmamap_sync((sc)->malo_rxdma.dd_dmat, \ 443177595Sweongyo (sc)->malo_rxdma.dd_dmamap, how); \ 444177595Sweongyo} while (0) 445177595Sweongyo 446177595Sweongyostruct malo_rxbuf { 447177595Sweongyo STAILQ_ENTRY(malo_rxbuf) bf_list; 448177595Sweongyo void *bf_desc; /* h/w descriptor */ 449177595Sweongyo bus_addr_t bf_daddr; /* physical addr of desc */ 450177595Sweongyo bus_dmamap_t bf_dmamap; 451177595Sweongyo bus_addr_t bf_data; /* physical addr of rx data */ 452177595Sweongyo struct mbuf *bf_m; /* jumbo mbuf */ 453177595Sweongyo}; 454177595Sweongyotypedef STAILQ_HEAD(, malo_rxbuf) malo_rxbufhead; 455177595Sweongyo 456177595Sweongyo/* 457177595Sweongyo * Software backed version of tx/rx descriptors. We keep 458177595Sweongyo * the software state out of the h/w descriptor structure 459177595Sweongyo * so that may be allocated in uncached memory w/o paying 460177595Sweongyo * performance hit. 461177595Sweongyo */ 462177595Sweongyostruct malo_txbuf { 463177595Sweongyo STAILQ_ENTRY(malo_txbuf) bf_list; 464177595Sweongyo void *bf_desc; /* h/w descriptor */ 465177595Sweongyo bus_addr_t bf_daddr; /* physical addr of desc */ 466177595Sweongyo bus_dmamap_t bf_dmamap; /* DMA map for descriptors */ 467177595Sweongyo int bf_nseg; 468177595Sweongyo bus_dma_segment_t bf_segs[MALO_TXDESC]; 469177595Sweongyo struct mbuf *bf_m; 470177595Sweongyo struct ieee80211_node *bf_node; 471177595Sweongyo struct malo_txq *bf_txq; /* backpointer to tx q/ring */ 472177595Sweongyo}; 473177595Sweongyotypedef STAILQ_HEAD(, malo_txbuf) malo_txbufhead; 474177595Sweongyo 475177595Sweongyo/* 476177595Sweongyo * TX/RX ring definitions. There are 4 tx rings, one 477177595Sweongyo * per AC, and 1 rx ring. Note carefully that transmit 478177595Sweongyo * descriptors are treated as a contiguous chunk and the 479177595Sweongyo * firmware pre-fetches descriptors. This means that we 480177595Sweongyo * must preserve order when moving descriptors between 481177595Sweongyo * the active+free lists; otherwise we may stall transmit. 482177595Sweongyo */ 483177595Sweongyostruct malo_txq { 484177595Sweongyo struct malo_descdma dma; /* bus dma resources */ 485177595Sweongyo struct mtx lock; /* tx q lock */ 486177595Sweongyo char name[12]; /* e.g. "malo0_txq4" */ 487177595Sweongyo int qnum; /* f/w q number */ 488177595Sweongyo int txpri; /* f/w tx priority */ 489177595Sweongyo int nfree; /* # buffers on free list */ 490177595Sweongyo malo_txbufhead free; /* queue of free buffers */ 491177595Sweongyo malo_txbufhead active; /* queue of active buffers */ 492177595Sweongyo}; 493177595Sweongyo 494177595Sweongyo#define MALO_TXQ_LOCK_INIT(_sc, _tq) do { \ 495177595Sweongyo snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \ 496177595Sweongyo device_get_nameunit((_sc)->malo_dev), (_tq)->qnum); \ 497177595Sweongyo mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \ 498177595Sweongyo} while (0) 499177595Sweongyo#define MALO_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->lock) 500177595Sweongyo#define MALO_TXQ_LOCK(_tq) mtx_lock(&(_tq)->lock) 501177595Sweongyo#define MALO_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->lock) 502177595Sweongyo#define MALO_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->lock, MA_OWNED) 503177595Sweongyo 504177595Sweongyo/* 505177595Sweongyo * Each packet has fixed front matter: a 2-byte length 506177595Sweongyo * of the payload, followed by a 4-address 802.11 header 507177595Sweongyo * (regardless of the actual header and always w/o any 508177595Sweongyo * QoS header). The payload then follows. 509177595Sweongyo */ 510177595Sweongyostruct malo_txrec { 511177595Sweongyo uint16_t fwlen; 512177595Sweongyo struct ieee80211_frame_addr4 wh; 513177595Sweongyo} __packed; 514177595Sweongyo 515178354Ssamstruct malo_vap { 516178354Ssam struct ieee80211vap malo_vap; 517178354Ssam int (*malo_newstate)(struct ieee80211vap *, 518178354Ssam enum ieee80211_state, int); 519178354Ssam}; 520178354Ssam#define MALO_VAP(vap) ((struct malo_vap *)(vap)) 521178354Ssam 522177595Sweongyostruct malo_softc { 523177595Sweongyo device_t malo_dev; 524177595Sweongyo struct ifnet *malo_ifp; /* interface common */ 525177595Sweongyo struct mtx malo_mtx; /* master lock (recursive) */ 526177595Sweongyo struct taskqueue *malo_tq; /* private task queue */ 527177595Sweongyo 528177595Sweongyo bus_dma_tag_t malo_dmat; /* bus DMA tag */ 529177595Sweongyo bus_space_handle_t malo_io0h; /* BAR 0 */ 530177595Sweongyo bus_space_tag_t malo_io0t; 531177595Sweongyo bus_space_handle_t malo_io1h; /* BAR 1 */ 532177595Sweongyo bus_space_tag_t malo_io1t; 533177595Sweongyo 534177595Sweongyo unsigned int malo_invalid : 1,/* disable hardware accesses */ 535177595Sweongyo malo_recvsetup : 1, /* recv setup */ 536178354Ssam malo_fixedrate: 1; /* use fixed tx rate */ 537177595Sweongyo 538177595Sweongyo struct malo_hal *malo_mh; /* h/w access layer */ 539177595Sweongyo struct malo_hal_hwspec malo_hwspecs; /* h/w capabilities */ 540177595Sweongyo struct malo_hal_txrxdma malo_hwdma; /* h/w dma setup */ 541177595Sweongyo uint32_t malo_imask; /* interrupt mask copy */ 542177595Sweongyo struct malo_hal_channel malo_curchan; 543177595Sweongyo u_int16_t malo_rxantenna; /* rx antenna */ 544177595Sweongyo u_int16_t malo_txantenna; /* tx antenna */ 545177595Sweongyo 546177595Sweongyo struct malo_descdma malo_rxdma; /* rx bus dma resources */ 547177595Sweongyo malo_rxbufhead malo_rxbuf; /* rx buffers */ 548177595Sweongyo struct malo_rxbuf *malo_rxnext; /* next rx buffer to process */ 549177595Sweongyo struct task malo_rxtask; /* rx int processing */ 550177595Sweongyo 551177595Sweongyo struct malo_txq malo_txq[MALO_NUM_TX_QUEUES]; 552177595Sweongyo struct task malo_txtask; /* tx int processing */ 553199559Sjhb struct callout malo_watchdog_timer; 554199559Sjhb int malo_timer; 555177595Sweongyo 556177595Sweongyo struct malo_tx_radiotap_header malo_tx_th; 557177595Sweongyo struct malo_rx_radiotap_header malo_rx_th; 558177595Sweongyo 559177595Sweongyo struct malo_stats malo_stats; /* interface statistics */ 560177595Sweongyo int malo_debug; 561177595Sweongyo}; 562177595Sweongyo 563177595Sweongyo#define MALO_LOCK_INIT(_sc) \ 564177595Sweongyo mtx_init(&(_sc)->malo_mtx, device_get_nameunit((_sc)->malo_dev), \ 565177595Sweongyo NULL, MTX_DEF | MTX_RECURSE) 566177595Sweongyo#define MALO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->malo_mtx) 567177595Sweongyo#define MALO_LOCK(_sc) mtx_lock(&(_sc)->malo_mtx) 568177595Sweongyo#define MALO_UNLOCK(_sc) mtx_unlock(&(_sc)->malo_mtx) 569177595Sweongyo#define MALO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->malo_mtx, MA_OWNED) 570177595Sweongyo 571177595Sweongyo#define MALO_RXFREE_INIT(_sc) \ 572177595Sweongyo mtx_init(&(_sc)->malo_rxlock, device_get_nameunit((_sc)->malo_dev), \ 573177595Sweongyo NULL, MTX_DEF) 574177595Sweongyo#define MALO_RXFREE_DESTROY(_sc) mtx_destroy(&(_sc)->malo_rxlock) 575177595Sweongyo#define MALO_RXFREE_LOCK(_sc) mtx_lock(&(_sc)->malo_rxlock) 576177595Sweongyo#define MALO_RXFREE_UNLOCK(_sc) mtx_unlock(&(_sc)->malo_rxlock) 577177595Sweongyo#define MALO_RXFREE_ASSERT(_sc) mtx_assert(&(_sc)->malo_rxlock, \ 578177595Sweongyo MA_OWNED) 579177595Sweongyo 580177595Sweongyoint malo_attach(uint16_t, struct malo_softc *); 581177595Sweongyoint malo_intr(void *); 582177595Sweongyoint malo_detach(struct malo_softc *); 583177595Sweongyovoid malo_shutdown(struct malo_softc *); 584177595Sweongyovoid malo_suspend(struct malo_softc *); 585177595Sweongyovoid malo_resume(struct malo_softc *); 586177595Sweongyo 587177595Sweongyo#endif 588