This diff switches athn(4) USB devices to open source firmware.

I only have an AR9271 device which I can test with:
athn0 at uhub1 port 2 configuration 1 interface 0 "ATHEROS USB2.0 WLAN" rev 
2.00/1.08 addr 3
athn0: AR9271 rev 1 (1T1R), ROM rev 13, address xx:xx:xx:xx:xx:xx

The diff switches AR7010 devices over as well because this new code
will *not* support the old binary-only firmware anyway.
But it is possible that AR7010 devices don't work yet with this diff.
Can anybody help and test such a device? And if anyone would like to
donate an AR7010 device for me to develop with, that would be appreciated.

The new firmware package 'athn-firmware-1.1p3', which contains the open
firmware files, is required. Specifically, the diff needs these files
from the new firmware package:

  /etc/firmware/athn-open-ar7010
  /etc/firmware/athn-open-ar9271

The firmware mirrors currently still ship version 1.1p2 which lacks the
open firmware files. But the pre-built firmware images are already part
of package mirrors, so a new firmware package can be built without
having to first cross-compile the firmware, like this:

  pkg_delete athn-firmware  # else conflict during install, no idea why
  cd /usr/ports/sysutils/firmware/athn
  make FETCH_PACKAGES=Yes install

Thanks again to bentley@ for porting both the required cross toolchain
and the open ath9k firmware during p2k17!

Index: if_athn_usb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_athn_usb.c,v
retrieving revision 1.48
diff -u -p -r1.48 if_athn_usb.c
--- if_athn_usb.c       26 Oct 2017 15:00:28 -0000      1.48
+++ if_athn_usb.c       16 Nov 2017 23:24:55 -0000
@@ -629,12 +629,9 @@ athn_usb_load_firmware(struct athn_usb_s
        /* Determine which firmware image to load. */
        if (usc->flags & ATHN_USB_FLAG_AR7010) {
                dd = usbd_get_device_descriptor(usc->sc_udev);
-               if (UGETW(dd->bcdDevice) == 0x0202)
-                       name = "athn-ar7010-11";
-               else
-                       name = "athn-ar7010";
+               name = "athn-open-ar7010";
        } else
-               name = "athn-ar9271";
+               name = "athn-open-ar9271";
        /* Read firmware image from the filesystem. */
        if ((error = loadfirmware(name, &fw, &fwsize)) != 0) {
                printf("%s: failed loadfirmware of file %s (error %d)\n",
@@ -1033,7 +1030,9 @@ athn_usb_newstate_cb(struct athn_usb_sof
 
        s = splnet();
        ostate = ic->ic_state;
-       DPRINTF(("newstate %d -> %d\n", ostate, cmd->state));
+       DPRINTF(("newstate %s -> %s\n",
+           ieee80211_state_name[ostate],
+           ieee80211_state_name[cmd->state]));
 
        if (ostate == IEEE80211_S_RUN) {
                sta_index = ((struct athn_node *)ic->ic_bss)->sta_index;
@@ -1228,8 +1227,6 @@ athn_usb_create_node(struct athn_usb_sof
        memset(&sta, 0, sizeof(sta));
        IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr);
        IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid);
-       sta.associd = htobe16(ni->ni_associd);
-       sta.valid = 1;
        sta.sta_index = an->sta_index;
        sta.maxampdu = 0xffff;
        if (ni->ni_flags & IEEE80211_NODE_HT)
@@ -1522,7 +1519,6 @@ void
 athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, int len)
 {
        struct ar_wmi_cmd_hdr *wmi;
-       struct ar_wmi_evt_txrate *txrate;
        uint16_t cmd_id;
 
        if (__predict_false(len < sizeof(*wmi)))
@@ -1547,10 +1543,16 @@ athn_usb_rx_wmi_ctrl(struct athn_usb_sof
                athn_usb_swba(usc);
                break;
 #endif
-       case AR_WMI_EVT_TXRATE:
-               txrate = (struct ar_wmi_evt_txrate *)&wmi[1];
-               DPRINTF(("txrate=%d\n", betoh32(txrate->txrate)));
+       case AR_WMI_EVT_TXSTATUS: {
+#ifdef ATH_DEBUG
+               struct ar_wmi_evt_txstatus *ts;
+               int i;
+               ts = (struct ar_wmi_evt_txstatus *)&wmi[1];
+               for (i = 0; i < ts->count && i < AR_HTC_MAX_TX_STATUS; i++)
+                       DPRINTF(("ts[%d]=%d\n", i, ts->ts[i].rate));
+#endif
                break;
+       }
        case AR_WMI_EVT_FATAL:
                printf("%s: fatal firmware error\n", usc->usb_dev.dv_xname);
                break;
@@ -2286,13 +2288,9 @@ athn_usb_init(struct ifnet *ifp)
 
        /* Update target capabilities. */
        memset(&hic, 0, sizeof(hic));
-       hic.flags = htobe32(0x400c2400);
-       hic.flags_ext = htobe32(0x00106080);
        hic.ampdu_limit = htobe32(0x0000ffff);
        hic.ampdu_subframes = 20;
-       hic.protmode = 1;       /* XXX */
-       hic.lg_txchainmask = sc->txchainmask;
-       hic.ht_txchainmask = sc->txchainmask;
+       hic.txchainmask = sc->txchainmask;
        DPRINTF(("updating target configuration\n"));
        error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE,
            &hic, sizeof(hic), NULL);
Index: if_athn_usb.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_athn_usb.h,v
retrieving revision 1.8
diff -u -p -r1.8 if_athn_usb.h
--- if_athn_usb.h       8 Apr 2017 02:57:25 -0000       1.8
+++ if_athn_usb.h       16 Nov 2017 22:53:10 -0000
@@ -34,47 +34,45 @@
 /* Wireless module interface commands. */
 #define AR_WMI_CMD_ECHO                        0x001
 #define AR_WMI_CMD_ACCESS_MEMORY       0x002
-#define AR_WMI_CMD_DISABLE_INTR                0x003
-#define AR_WMI_CMD_ENABLE_INTR         0x004
-#define AR_WMI_CMD_RX_LINK             0x005
+#define AR_WMI_GET_FW_VERSION          0x003
+#define AR_WMI_CMD_DISABLE_INTR                0x004
+#define AR_WMI_CMD_ENABLE_INTR         0x005
 #define AR_WMI_CMD_ATH_INIT            0x006
 #define AR_WMI_CMD_ABORT_TXQ           0x007
 #define AR_WMI_CMD_STOP_TX_DMA         0x008
-#define AR_WMI_CMD_STOP_DMA_RECV       0x009
-#define AR_WMI_CMD_ABORT_TX_DMA                0x00a
-#define AR_WMI_CMD_DRAIN_TXQ           0x00b
-#define AR_WMI_CMD_DRAIN_TXQ_ALL       0x00c
-#define AR_WMI_CMD_START_RECV          0x00d
-#define AR_WMI_CMD_STOP_RECV           0x00e
-#define AR_WMI_CMD_FLUSH_RECV          0x00f
-#define AR_WMI_CMD_SET_MODE            0x010
-#define AR_WMI_CMD_RESET               0x011
-#define AR_WMI_CMD_NODE_CREATE         0x012
-#define AR_WMI_CMD_NODE_REMOVE         0x013
-#define AR_WMI_CMD_VAP_REMOVE          0x014
-#define AR_WMI_CMD_VAP_CREATE          0x015
-#define AR_WMI_CMD_BEACON_UPDATE       0x016
-#define AR_WMI_CMD_REG_READ            0x017
-#define AR_WMI_CMD_REG_WRITE           0x018
-#define AR_WMI_CMD_RC_STATE_CHANGE     0x019
-#define AR_WMI_CMD_RC_RATE_UPDATE      0x01a
-#define AR_WMI_CMD_DEBUG_INFO          0x01b
-#define AR_WMI_CMD_HOST_ATTACH         0x01c
-#define AR_WMI_CMD_TARGET_IC_UPDATE    0x01d
-#define AR_WMI_CMD_TGT_STATS           0x01e
-#define AR_WMI_CMD_TX_AGGR_ENABLE      0x01f
+#define AR_WMI_CMD_ABORT_TX_DMA                0x009
+#define AR_WMI_CMD_DRAIN_TXQ           0x00a
+#define AR_WMI_CMD_DRAIN_TXQ_ALL       0x00b
+#define AR_WMI_CMD_START_RECV          0x00c
+#define AR_WMI_CMD_STOP_RECV           0x00d
+#define AR_WMI_CMD_FLUSH_RECV          0x00e
+#define AR_WMI_CMD_SET_MODE            0x00f
+#define AR_WMI_CMD_NODE_CREATE         0x010
+#define AR_WMI_CMD_NODE_REMOVE         0x011
+#define AR_WMI_CMD_VAP_REMOVE          0x012
+#define AR_WMI_CMD_VAP_CREATE          0x013
+#define AR_WMI_CMD_REG_READ            0x014
+#define AR_WMI_CMD_REG_WRITE           0x015
+#define AR_WMI_CMD_RC_STATE_CHANGE     0x016
+#define AR_WMI_CMD_RC_RATE_UPDATE      0x017
+#define AR_WMI_CMD_TARGET_IC_UPDATE    0x018
+#define AR_WMI_CMD_TX_AGGR_ENABLE      0x019
 #define AR_WMI_CMD_TGT_DETACH          0x020
-#define AR_WMI_CMD_TGT_TXQ_ENABLE      0x021
-#define AR_WMI_CMD_AGGR_LIMIT          0x026
+#define AR_WMI_CMD_NODE_UPDATE         0x021
+#define AR_WMI_CMD_INT_STATS           0x022
+#define AR_WMI_CMD_TX_STATS            0x023
+#define AR_WMI_CMD_RX_STATS            0x024
+#define AR_WMI_CMD_BITRATE_MASK                0x025
+#define AR_WMI_CMD_REG_RMW             0x026
+
 /* Wireless module interface events. */
 #define AR_WMI_EVT_TGT_RDY             0x001
 #define AR_WMI_EVT_SWBA                        0x002
 #define AR_WMI_EVT_FATAL               0x003
 #define AR_WMI_EVT_TXTO                        0x004
 #define AR_WMI_EVT_BMISS               0x005
-#define AR_WMI_EVT_WLAN_TXCOMP         0x006
-#define AR_WMI_EVT_DELBA               0x007
-#define AR_WMI_EVT_TXRATE              0x008
+#define AR_WMI_EVT_DELBA               0x006
+#define AR_WMI_EVT_TXSTATUS            0x007
 
 /* Structure for service AR_SVC_WMI_CONTROL. */
 struct ar_wmi_cmd_hdr {
@@ -85,15 +83,8 @@ struct ar_wmi_cmd_hdr {
 } __packed;
 
 /* Values for AR_WMI_CMD_SET_MODE. */
-#define AR_HTC_MODE_AUTO       0
-#define AR_HTC_MODE_11A                1
-#define AR_HTC_MODE_11B                2
-#define AR_HTC_MODE_11G                3
-#define AR_HTC_MODE_FH         4
-#define AR_HTC_MODE_TURBO_A    5
-#define AR_HTC_MODE_TURBO_G    6
-#define AR_HTC_MODE_11NA       7
-#define AR_HTC_MODE_11NG       8
+#define AR_HTC_MODE_11NA       0
+#define AR_HTC_MODE_11NG       1
 
 #define AR_MAX_WRITE_COUNT     32
 /* Structure for command AR_WMI_CMD_REG_WRITE. */
@@ -104,14 +95,11 @@ struct ar_wmi_cmd_reg_write {
 
 /* Structure for command AR_WMI_CMD_NODE_{CREATE,REMOVE}. */
 struct ar_htc_target_sta {
-       uint16_t        associd;
-       uint16_t        txpower;
-       uint32_t        pariwisekey;
        uint8_t         macaddr[IEEE80211_ADDR_LEN];
        uint8_t         bssid[IEEE80211_ADDR_LEN];
        uint8_t         sta_index;
        uint8_t         vif_index;
-       uint8_t         vif_sta;
+       uint8_t         is_vif_sta;
        uint16_t        flags;
 #define AR_HTC_STA_AUTH        0x0001
 #define AR_HTC_STA_QOS 0x0002
@@ -119,14 +107,14 @@ struct ar_htc_target_sta {
 #define AR_HTC_STA_HT  0x0008
 
        uint16_t        htcap;
-       uint8_t         valid;
-       uint16_t        capinfo;
-       uint32_t        reserved[2];
-       uint16_t        txseqmgmt;
-       uint8_t         is_vif_sta;
        uint16_t        maxampdu;
+       uint8_t         pad;
+
+       /* Internal state. */
+       uint16_t        txseqmgmt;
        uint16_t        iv16;
        uint32_t        iv32;
+       void            *ni_vap;
 } __packed;
 
 /* Structures for command AR_WMI_CMD_RC_RATE_UPDATE. */
@@ -139,12 +127,14 @@ struct ar_htc_rateset {
 struct ar_htc_target_rate {
        uint8_t                 sta_index;
        uint8_t                 isnew;
+       uint8_t                 pad[2];
        uint32_t                capflags;
-#define AR_RC_DS_FLAG  0x00000001
-#define AR_RC_40_FLAG  0x00000002
-#define AR_RC_SGI_FLAG 0x00000004
-#define AR_RC_HT_FLAG  0x00000008
-#define AR_RC_STBC_FLAG        0x00000020
+#define AR_RC_DS_FLAG          0x00000001
+#define AR_RC_40_FLAG          0x00000002
+#define AR_RC_SGI_FLAG         0x00000004
+#define AR_RC_HT_FLAG          0x00000008
+#define AR_RC_STBC_FLAG                0x00000030 /* 2 bits */
+#define AR_RC_WEP_TKIP_FLAG    0x00000100 
 
        struct ar_htc_rateset   lg_rates;
        struct ar_htc_rateset   ht_rates;
@@ -161,7 +151,6 @@ struct ar_htc_target_aggr {
 /* Structure for command AR_WMI_CMD_VAP_CREATE. */
 struct ar_htc_target_vif {
        uint8_t         index;
-       uint8_t         des_bssid[IEEE80211_ADDR_LEN];
        uint32_t        opmode;
 #define AR_HTC_M_IBSS          0
 #define AR_HTC_M_STA           1
@@ -169,41 +158,44 @@ struct ar_htc_target_vif {
 #define AR_HTC_M_AHDEMO                3
 #define AR_HTC_M_HOSTAP                6
 #define AR_HTC_M_MONITOR       8
-
        uint8_t         myaddr[IEEE80211_ADDR_LEN];
-       uint8_t         bssid[IEEE80211_ADDR_LEN];
-       uint32_t        flags;
-       uint32_t        flags_ext;
-       uint16_t        ps_sta;
-       uint16_t        rtsthreshold;
        uint8_t         ath_cap;
-       int8_t          mcast_rate;
+       uint16_t        rtsthreshold;
+       uint8_t         pad;
+
+       /* Internal state. */
+       int8_t          nodeindex;
+       void            *iv_bss;
 } __packed;
 
 /* Structure for command AM_WMI_CMD_TARGET_IC_UPDATE. */
 struct ar_htc_cap_target {
-       uint32_t        flags;
-       uint32_t        flags_ext;
        uint32_t        ampdu_limit;
        uint8_t         ampdu_subframes;
-       uint8_t         ht_txchainmask;
-       uint8_t         lg_txchainmask;
-       uint8_t         rtscts_ratecode;
-       uint8_t         protmode;
+       uint8_t         enable_coex;
+       uint8_t         txchainmask;
+       uint8_t         pad;
 } __packed;
 
-/* Structure for event AR_WMI_EVT_TXRATE. */
-struct ar_wmi_evt_txrate {
-       uint32_t        txrate;
-       uint8_t         rssi_thresh;
-       uint8_t         per;
+#define AR_HTC_MAX_TX_STATUS 12
+
+/* Structure for event AR_WMI_EVT_TXSTATUS. */
+struct ar_wmi_evt_txstatus {
+       uint8_t                 count;
+       struct {
+               uint8_t         cookie;
+               uint8_t         rate;
+               uint8_t         flags;
+       } ts[AR_HTC_MAX_TX_STATUS];
 } __packed;
 
 /* HTC header. */
 struct ar_htc_frame_hdr {
        uint8_t         endpoint_id;
        uint8_t         flags;
-#define AR_HTC_FLAG_TRAILER    0x02
+#define AR_HTC_FLAG_NEED_CREDIT_UPDATE         0x01
+#define AR_HTC_FLAG_TRAILER                    0x02
+#define AR_HTC_FLAG_CREDIT_REDISTRIBUTION      0x03
 
        uint16_t        payload_len;
        uint8_t         control[4];
@@ -236,7 +228,8 @@ struct ar_tx_frame {
 
        uint8_t         key_type;
        uint8_t         key_idx;
-       uint8_t         reserved[26];
+       uint8_t         cookie;
+       uint8_t         pad;
 } __packed;
 
 /* Structure for service AR_SVC_WMI_MGMT. */
@@ -247,7 +240,8 @@ struct ar_tx_mgmt {
        uint8_t         flags;
        uint8_t         key_type;
        uint8_t         key_idx;
-       uint16_t        reserved;
+       uint8_t         cookie;
+       uint8_t         pad;
 } __packed;
 
 /* Structure for service AR_SVC_WMI_BEACON. */

Reply via email to