Skip to content

Commit

Permalink
Merge pull request #579 from DrSchottky/pico-w
Browse files Browse the repository at this point in the history
Add monitor mode support for Raspberry Pi Pico W (bcm43439a0)  FW 7_95_49_2271bb6
  • Loading branch information
jlinktu authored Oct 26, 2023
2 parents e357a19 + 98b1a47 commit 8df2379
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 2 deletions.
64 changes: 62 additions & 2 deletions firmwares/bcm43439a0/structs.common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
#define PAD _XSTR(__LINE__)
#endif

struct wl_rxsts {
uint pkterror;
uint phytype;
uint16 chanspec;
uint16 datarate;
uint8 mcs;
uint8 htflags;
uint antenna;
uint pktlength;
uint32 mactime;
uint sq;
int32 signal;
int32 noise;
uint preamble;
uint encoding;
uint nfrmtype;
struct wl_if *wlif;
} __attribute__((packed));

struct sk_buff {
union { /* 0x000 */
uint32 u32;
Expand Down Expand Up @@ -953,6 +972,47 @@ struct wlc_hw_info {
uint32 PAD; /* 0x168 */
} __attribute__((packed));

struct wlc_if_stats {
/* transmit stat counters */
uint32 txframe; /* tx data frames */
uint32 txbyte; /* tx data bytes */
uint32 txerror; /* tx data errors (derived: sum of others) */
uint32 txnobuf; /* tx out of buffer errors */
uint32 txrunt; /* tx runt frames */
uint32 txfail; /* tx failed frames */
uint32 rxframe; /* rx data frames */
uint32 rxbyte; /* rx data bytes */
uint32 rxerror; /* rx data errors (derived: sum of others) */
uint32 rxnobuf; /* rx out of buffer errors */
uint32 rxrunt; /* rx runt frames */
uint32 rxfragerr; /* rx fragment errors */
uint32 txretry; /* tx retry frames */
uint32 txretrie; /* tx multiple retry frames */
uint32 txfrmsnt; /* tx sent frames */
uint32 txmulti; /* tx mulitcast sent frames */
uint32 txfrag; /* tx fragments sent */
uint32 rxmulti; /* rx multicast frames */
};

struct wl_if {
struct wlc_if *wlcif;
struct hndrte_dev *dev;
};

struct wlc_if {
struct wlc_if *next;
uint8 type;
uint8 index;
uint8 flags;
struct wl_if *wlif;
void *qi;
union {
struct scb *scb;
struct wlc_bsscfg *bsscfg;
} u;
struct wlc_if_stats _cnt;
};

struct wlc_info {
void *pub; /* 0x000 */
void *osh; /* 0x004 */
Expand Down Expand Up @@ -1083,7 +1143,7 @@ struct wlc_info {
uint32 PAD; /* 0x1f8 */
uint32 PAD; /* 0x1fc */
uint32 PAD; /* 0x200 */
uint32 PAD; /* 0x204 */
uint32 monitor; /* 0x204 */
uint32 PAD; /* 0x208 */
uint32 PAD; /* 0x20c */
uint32 PAD; /* 0x210 */
Expand Down Expand Up @@ -1320,7 +1380,7 @@ struct wlc_info {
uint32 PAD; /* 0x5ac */
uint32 PAD; /* 0x5b0 */
uint32 PAD; /* 0x5b4 */
uint32 PAD; /* 0x5b8 */
struct wlc_if *wlcif_list; /* 0x5b8 */
uint32 PAD; /* 0x5bc */
uint32 PAD; /* 0x5c0 */
uint32 PAD; /* 0x5c4 */
Expand Down
39 changes: 39 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/brcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma once

#include "../include/types.h"
#define WL_CHANSPEC_CHAN_MASK 0x00ff
#define CHSPEC_CHANNEL(chspec) ((uint8_t)((chspec) & WL_CHANSPEC_CHAN_MASK))
88 changes: 88 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/d11.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma once

struct d11rxhdr {
unsigned short RxFrameSize; /* Actual byte length of the frame data received */
unsigned short PAD;
unsigned short PhyRxStatus_0; /* PhyRxStatus 15:0 */
unsigned short PhyRxStatus_1; /* PhyRxStatus 31:16 */
unsigned short PhyRxStatus_2; /* PhyRxStatus 47:32 */
unsigned short PhyRxStatus_3; /* PhyRxStatus 63:48 */
unsigned short PhyRxStatus_4; /* PhyRxStatus 79:64 */
unsigned short PhyRxStatus_5; /* PhyRxStatus 95:80 */
unsigned short RxStatus1; /* MAC Rx status */
unsigned short RxStatus2; /* extended MAC Rx status */
unsigned short RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
unsigned short RxChan; /* gain code, channel radio code, and phy type -> looks like chanspec */
} __attribute__((packed));

/* ucode RxStatus1: */
#define RXS_BCNSENT 0x8000
#define RXS_SECKINDX_MASK 0x07e0
#define RXS_SECKINDX_SHIFT 5
#define RXS_DECERR (1 << 4)
#define RXS_DECATMPT (1 << 3)
/* PAD bytes to make IP data 4 bytes aligned */
#define RXS_PBPRES (1 << 2)
#define RXS_RESPFRAMETX (1 << 1)
#define RXS_FCSERR (1 << 0)

/* ucode RxStatus2: */
#define RXS_AMSDU_MASK 1
#define RXS_AGGTYPE_MASK 0x6
#define RXS_AGGTYPE_SHIFT 1
#define RXS_PHYRXST_VALID (1 << 8)
#define RXS_RXANT_MASK 0x3
#define RXS_RXANT_SHIFT 12

/* RxChan */
#define RXS_CHAN_40 0x1000
#define RXS_CHAN_5G 0x0800
#define RXS_CHAN_ID_MASK 0x07f8
#define RXS_CHAN_ID_SHIFT 3
#define RXS_CHAN_PHYTYPE_MASK 0x0007
#define RXS_CHAN_PHYTYPE_SHIFT 0

struct wlc_d11rxhdr {
struct d11rxhdr rxhdr;
unsigned int tsf_l;
char rssi; /* computed instanteneous RSSI in BMAC */
char rxpwr0;
char rxpwr1;
char do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */
char rxpwr[4]; /* rssi for supported antennas */
} __attribute__((packed));

40 changes: 40 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/include/local_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#ifndef LOCAL_WRAPPER_H
#define LOCAL_WRAPPER_H

#include "../src/local_wrapper.c" // wrapper definitions for functions that already exist in the firmware

#endif /*LOCAL_WRAPPER_H*/
113 changes: 113 additions & 0 deletions patches/bcm43439a0/7_95_49_2271bb6/nexmon/src/monitormode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/***************************************************************************
* *
* ########### ########### ########## ########## *
* ############ ############ ############ ############ *
* ## ## ## ## ## ## ## *
* ## ## ## ## ## ## ## *
* ########### #### ###### ## ## ## ## ###### *
* ########### #### # ## ## ## ## # # *
* ## ## ###### ## ## ## ## # # *
* ## ## # ## ## ## ## # # *
* ############ ##### ###### ## ## ## ##### ###### *
* ########### ########### ## ## ## ########## *
* *
* S E C U R E M O B I L E N E T W O R K I N G *
* *
* This file is part of NexMon. *
* *
* Copyright (c) 2016 NexMon Team *
* *
* NexMon is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* NexMon is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with NexMon. If not, see <http://www.gnu.org/licenses/>. *
* *
**************************************************************************/

#pragma NEXMON targetregion "patch"

#include <firmware_version.h>
#include <wrapper.h> // wrapper definitions for functions that already exist in the firmware
#include <structs.h> // structures that are used by the code in the firmware
#include <patcher.h>
#include <helper.h>
#include "d11.h"
#include "brcm.h"

//#define RADIOTAP_MCS
#include <ieee80211_radiotap.h>

#define MONITOR_DISABLED 0
#define MONITOR_IEEE80211 1
#define MONITOR_RADIOTAP 2
#define MONITOR_LOG_ONLY 3
#define MONITOR_DROP_FRM 4
#define MONITOR_IPV4_UDP 5

void
wl_monitor_radiotap(struct wl_info *wl, struct wl_rxsts *sts, struct sk_buff *p) {
struct sk_buff *p_new = pkt_buf_get_skb(wl->wlc->osh, p->len + sizeof(struct nexmon_radiotap_header));
struct nexmon_radiotap_header *frame = (struct nexmon_radiotap_header *) p_new->data;
struct tsf tsf;
wlc_bmac_read_tsf(wl->wlc_hw, &tsf.tsf_l, &tsf.tsf_h);

frame->header.it_version = 0;
frame->header.it_pad = 0;
frame->header.it_len = sizeof(struct nexmon_radiotap_header);
frame->header.it_present =
(1<<IEEE80211_RADIOTAP_TSFT)
| (1<<IEEE80211_RADIOTAP_FLAGS)
| (1<<IEEE80211_RADIOTAP_CHANNEL)
| (1<<IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
frame->tsf.tsf_l = tsf.tsf_l;
frame->tsf.tsf_h = tsf.tsf_h;
frame->flags = IEEE80211_RADIOTAP_F_FCS;
frame->chan_freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(sts->chanspec));
frame->chan_flags = 0;
frame->dbm_antsignal = sts->signal;

memcpy(p_new->data + sizeof(struct nexmon_radiotap_header), p->data + 6, p->len - 6);

p_new->len -= 6;

if (wl->wlc->wlcif_list->next)
wl->wlc->wlcif_list->wlif->dev->chained->funcs->xmit(wl->wlc->wlcif_list->wlif->dev, wl->wlc->wlcif_list->wlif->dev->chained, p_new);
else
wl->dev->chained->funcs->xmit(wl->dev, wl->dev->chained, p_new);
}

void
wl_monitor_hook(struct wl_info *wl, struct wl_rxsts *sts, struct sk_buff *p) {
switch(wl->wlc->monitor & 0xFF) {
case MONITOR_RADIOTAP:
wl_monitor_radiotap(wl, sts, p);
break;

case MONITOR_IEEE80211:
wl_monitor(wl, sts, p);
break;

case MONITOR_LOG_ONLY:
printf("frame received\n");
break;

case MONITOR_DROP_FRM:
break;

case MONITOR_IPV4_UDP:
printf("%s: udp tunneling not implemented\n");
// not implemented yet
break;
}
}

__attribute__((at(0x81F6D6, "flashpatch", CHIP_VER_BCM43439a0, FW_VER_ALL)))
BLPatch(flash_patch_76, wl_monitor_hook);
Loading

0 comments on commit 8df2379

Please sign in to comment.