Skip to content

Commit 3e394ef

Browse files
committed
Merge branch 'ieee802154-for-davem-2017-12-04' of git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next
Stefan Schmidt says: ==================== pull-request: ieee802154-next 2017-12-04 Some update from ieee802154 to *net-next* Jian-Hong Pan updated our docs to match the APIs in code. Michael Hennerichs enhanced the adf7242 driver to work with adf7241 devices and reworked the IRQ and packet handling in the driver. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 1dfc266 + 8f1878a commit 3e394ef

File tree

3 files changed

+105
-27
lines changed

3 files changed

+105
-27
lines changed

Documentation/devicetree/bindings/net/ieee802154/adf7242.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
* ADF7242 IEEE 802.15.4 *
22

33
Required properties:
4-
- compatible: should be "adi,adf7242"
4+
- compatible: should be "adi,adf7242", "adi,adf7241"
55
- spi-max-frequency: maximal bus speed (12.5 MHz)
66
- reg: the chipselect index
77
- interrupts: the interrupt generated by the device via pin IRQ1.

Documentation/networking/ieee802154.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,46 @@ The include/net/mac802154.h defines following functions:
9797
- void ieee802154_unregister_hw(struct ieee802154_hw *hw):
9898
freeing registered PHY
9999

100+
- void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,
101+
u8 lqi):
102+
telling 802.15.4 module there is a new received frame in the skb with
103+
the RF Link Quality Indicator (LQI) from the hardware device
104+
105+
- void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
106+
bool ifs_handling):
107+
telling 802.15.4 module the frame in the skb is or going to be
108+
transmitted through the hardware device
109+
110+
The device driver must implement the following callbacks in the IEEE 802.15.4
111+
operations structure at least:
112+
struct ieee802154_ops {
113+
...
114+
int (*start)(struct ieee802154_hw *hw);
115+
void (*stop)(struct ieee802154_hw *hw);
116+
...
117+
int (*xmit_async)(struct ieee802154_hw *hw, struct sk_buff *skb);
118+
int (*ed)(struct ieee802154_hw *hw, u8 *level);
119+
int (*set_channel)(struct ieee802154_hw *hw, u8 page, u8 channel);
120+
...
121+
};
122+
123+
- int start(struct ieee802154_hw *hw):
124+
handler that 802.15.4 module calls for the hardware device initialization.
125+
126+
- void stop(struct ieee802154_hw *hw):
127+
handler that 802.15.4 module calls for the hardware device cleanup.
128+
129+
- int xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb):
130+
handler that 802.15.4 module calls for each frame in the skb going to be
131+
transmitted through the hardware device.
132+
133+
- int ed(struct ieee802154_hw *hw, u8 *level):
134+
handler that 802.15.4 module calls for Energy Detection from the hardware
135+
device.
136+
137+
- int set_channel(struct ieee802154_hw *hw, u8 page, u8 channel):
138+
set radio for listening on specific channel of the hardware device.
139+
100140
Moreover IEEE 802.15.4 device operations structure should be filled.
101141

102142
Fake drivers

drivers/net/ieee802154/adf7242.c

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Analog Devices ADF7242 Low-Power IEEE 802.15.4 Transceiver
33
*
4-
* Copyright 2009-2015 Analog Devices Inc.
4+
* Copyright 2009-2017 Analog Devices Inc.
55
*
66
* Licensed under the GPL-2 or later.
77
*
@@ -344,12 +344,18 @@ static int adf7242_wait_status(struct adf7242_local *lp, unsigned int status,
344344
return ret;
345345
}
346346

347-
static int adf7242_wait_ready(struct adf7242_local *lp, int line)
347+
static int adf7242_wait_rc_ready(struct adf7242_local *lp, int line)
348348
{
349349
return adf7242_wait_status(lp, STAT_RC_READY | STAT_SPI_READY,
350350
STAT_RC_READY | STAT_SPI_READY, line);
351351
}
352352

353+
static int adf7242_wait_spi_ready(struct adf7242_local *lp, int line)
354+
{
355+
return adf7242_wait_status(lp, STAT_SPI_READY,
356+
STAT_SPI_READY, line);
357+
}
358+
353359
static int adf7242_write_fbuf(struct adf7242_local *lp, u8 *data, u8 len)
354360
{
355361
u8 *buf = lp->buf;
@@ -369,7 +375,7 @@ static int adf7242_write_fbuf(struct adf7242_local *lp, u8 *data, u8 len)
369375
spi_message_add_tail(&xfer_head, &msg);
370376
spi_message_add_tail(&xfer_buf, &msg);
371377

372-
adf7242_wait_ready(lp, __LINE__);
378+
adf7242_wait_spi_ready(lp, __LINE__);
373379

374380
mutex_lock(&lp->bmux);
375381
buf[0] = CMD_SPI_PKT_WR;
@@ -401,7 +407,7 @@ static int adf7242_read_fbuf(struct adf7242_local *lp,
401407
spi_message_add_tail(&xfer_head, &msg);
402408
spi_message_add_tail(&xfer_buf, &msg);
403409

404-
adf7242_wait_ready(lp, __LINE__);
410+
adf7242_wait_spi_ready(lp, __LINE__);
405411

406412
mutex_lock(&lp->bmux);
407413
if (packet_read) {
@@ -432,7 +438,7 @@ static int adf7242_read_reg(struct adf7242_local *lp, u16 addr, u8 *data)
432438
.rx_buf = lp->buf_read_rx,
433439
};
434440

435-
adf7242_wait_ready(lp, __LINE__);
441+
adf7242_wait_spi_ready(lp, __LINE__);
436442

437443
mutex_lock(&lp->bmux);
438444
lp->buf_read_tx[0] = CMD_SPI_MEM_RD(addr);
@@ -462,7 +468,7 @@ static int adf7242_write_reg(struct adf7242_local *lp, u16 addr, u8 data)
462468
{
463469
int status;
464470

465-
adf7242_wait_ready(lp, __LINE__);
471+
adf7242_wait_spi_ready(lp, __LINE__);
466472

467473
mutex_lock(&lp->bmux);
468474
lp->buf_reg_tx[0] = CMD_SPI_MEM_WR(addr);
@@ -484,7 +490,7 @@ static int adf7242_cmd(struct adf7242_local *lp, unsigned int cmd)
484490
dev_vdbg(&lp->spi->dev, "%s : CMD=0x%X\n", __func__, cmd);
485491

486492
if (cmd != CMD_RC_PC_RESET_NO_WAIT)
487-
adf7242_wait_ready(lp, __LINE__);
493+
adf7242_wait_rc_ready(lp, __LINE__);
488494

489495
mutex_lock(&lp->bmux);
490496
lp->buf_cmd = cmd;
@@ -557,6 +563,22 @@ static int adf7242_verify_firmware(struct adf7242_local *lp,
557563
return 0;
558564
}
559565

566+
static void adf7242_clear_irqstat(struct adf7242_local *lp)
567+
{
568+
adf7242_write_reg(lp, REG_IRQ1_SRC1, IRQ_CCA_COMPLETE | IRQ_SFD_RX |
569+
IRQ_SFD_TX | IRQ_RX_PKT_RCVD | IRQ_TX_PKT_SENT |
570+
IRQ_FRAME_VALID | IRQ_ADDRESS_VALID | IRQ_CSMA_CA);
571+
}
572+
573+
static int adf7242_cmd_rx(struct adf7242_local *lp)
574+
{
575+
/* Wait until the ACK is sent */
576+
adf7242_wait_status(lp, RC_STATUS_PHY_RDY, RC_STATUS_MASK, __LINE__);
577+
adf7242_clear_irqstat(lp);
578+
579+
return adf7242_cmd(lp, CMD_RC_RX);
580+
}
581+
560582
static int adf7242_set_txpower(struct ieee802154_hw *hw, int mbm)
561583
{
562584
struct adf7242_local *lp = hw->priv;
@@ -660,7 +682,7 @@ static int adf7242_start(struct ieee802154_hw *hw)
660682
struct adf7242_local *lp = hw->priv;
661683

662684
adf7242_cmd(lp, CMD_RC_PHY_RDY);
663-
adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
685+
adf7242_clear_irqstat(lp);
664686
enable_irq(lp->spi->irq);
665687
set_bit(FLAG_START, &lp->flags);
666688

@@ -671,10 +693,10 @@ static void adf7242_stop(struct ieee802154_hw *hw)
671693
{
672694
struct adf7242_local *lp = hw->priv;
673695

696+
disable_irq(lp->spi->irq);
674697
adf7242_cmd(lp, CMD_RC_IDLE);
675698
clear_bit(FLAG_START, &lp->flags);
676-
disable_irq(lp->spi->irq);
677-
adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
699+
adf7242_clear_irqstat(lp);
678700
}
679701

680702
static int adf7242_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
@@ -789,9 +811,12 @@ static int adf7242_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
789811
struct adf7242_local *lp = hw->priv;
790812
int ret;
791813

814+
/* ensure existing instances of the IRQ handler have completed */
815+
disable_irq(lp->spi->irq);
792816
set_bit(FLAG_XMIT, &lp->flags);
793817
reinit_completion(&lp->tx_complete);
794818
adf7242_cmd(lp, CMD_RC_PHY_RDY);
819+
adf7242_clear_irqstat(lp);
795820

796821
ret = adf7242_write_fbuf(lp, skb->data, skb->len);
797822
if (ret)
@@ -800,6 +825,7 @@ static int adf7242_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
800825
ret = adf7242_cmd(lp, CMD_RC_CSMACA);
801826
if (ret)
802827
goto err;
828+
enable_irq(lp->spi->irq);
803829

804830
ret = wait_for_completion_interruptible_timeout(&lp->tx_complete,
805831
HZ / 10);
@@ -822,7 +848,7 @@ static int adf7242_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
822848

823849
err:
824850
clear_bit(FLAG_XMIT, &lp->flags);
825-
adf7242_cmd(lp, CMD_RC_RX);
851+
adf7242_cmd_rx(lp);
826852

827853
return ret;
828854
}
@@ -846,22 +872,22 @@ static int adf7242_rx(struct adf7242_local *lp)
846872

847873
skb = dev_alloc_skb(len);
848874
if (!skb) {
849-
adf7242_cmd(lp, CMD_RC_RX);
875+
adf7242_cmd_rx(lp);
850876
return -ENOMEM;
851877
}
852878

853879
data = skb_put(skb, len);
854880
ret = adf7242_read_fbuf(lp, data, len, true);
855881
if (ret < 0) {
856882
kfree_skb(skb);
857-
adf7242_cmd(lp, CMD_RC_RX);
883+
adf7242_cmd_rx(lp);
858884
return ret;
859885
}
860886

861887
lqi = data[len - 2];
862888
lp->rssi = data[len - 1];
863889

864-
adf7242_cmd(lp, CMD_RC_RX);
890+
ret = adf7242_cmd_rx(lp);
865891

866892
skb_trim(skb, len - 2); /* Don't put RSSI/LQI or CRC into the frame */
867893

@@ -870,7 +896,7 @@ static int adf7242_rx(struct adf7242_local *lp)
870896
dev_dbg(&lp->spi->dev, "%s: ret=%d len=%d lqi=%d rssi=%d\n",
871897
__func__, ret, (int)len, (int)lqi, lp->rssi);
872898

873-
return 0;
899+
return ret;
874900
}
875901

876902
static const struct ieee802154_ops adf7242_ops = {
@@ -888,7 +914,7 @@ static const struct ieee802154_ops adf7242_ops = {
888914
.set_cca_ed_level = adf7242_set_cca_ed_level,
889915
};
890916

891-
static void adf7242_debug(u8 irq1)
917+
static void adf7242_debug(struct adf7242_local *lp, u8 irq1)
892918
{
893919
#ifdef DEBUG
894920
u8 stat;
@@ -906,9 +932,12 @@ static void adf7242_debug(u8 irq1)
906932
irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
907933
irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
908934

909-
dev_dbg(&lp->spi->dev, "%s STATUS = %X:\n%s\n%s%s%s%s%s\n",
935+
dev_dbg(&lp->spi->dev, "%s STATUS = %X:\n%s\n%s\n%s\n%s\n%s%s%s%s%s\n",
910936
__func__, stat,
937+
stat & STAT_SPI_READY ? "SPI_READY" : "SPI_BUSY",
938+
stat & STAT_IRQ_STATUS ? "IRQ_PENDING" : "IRQ_CLEAR",
911939
stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
940+
stat & STAT_CCA_RESULT ? "CHAN_IDLE" : "CHAN_BUSY",
912941
(stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
913942
(stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
914943
(stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
@@ -923,20 +952,20 @@ static irqreturn_t adf7242_isr(int irq, void *data)
923952
unsigned int xmit;
924953
u8 irq1;
925954

926-
adf7242_wait_status(lp, RC_STATUS_PHY_RDY, RC_STATUS_MASK, __LINE__);
927-
928955
adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1);
929-
adf7242_write_reg(lp, REG_IRQ1_SRC1, irq1);
930956

931957
if (!(irq1 & (IRQ_RX_PKT_RCVD | IRQ_CSMA_CA)))
932958
dev_err(&lp->spi->dev, "%s :ERROR IRQ1 = 0x%X\n",
933959
__func__, irq1);
934960

935-
adf7242_debug(irq1);
961+
adf7242_debug(lp, irq1);
936962

937963
xmit = test_bit(FLAG_XMIT, &lp->flags);
938964

939965
if (xmit && (irq1 & IRQ_CSMA_CA)) {
966+
adf7242_wait_status(lp, RC_STATUS_PHY_RDY,
967+
RC_STATUS_MASK, __LINE__);
968+
940969
if (ADF7242_REPORT_CSMA_CA_STAT) {
941970
u8 astat;
942971

@@ -957,6 +986,7 @@ static irqreturn_t adf7242_isr(int irq, void *data)
957986
lp->tx_stat = SUCCESS;
958987
}
959988
complete(&lp->tx_complete);
989+
adf7242_clear_irqstat(lp);
960990
} else if (!xmit && (irq1 & IRQ_RX_PKT_RCVD) &&
961991
(irq1 & IRQ_FRAME_VALID)) {
962992
adf7242_rx(lp);
@@ -965,16 +995,19 @@ static irqreturn_t adf7242_isr(int irq, void *data)
965995
dev_dbg(&lp->spi->dev, "%s:%d : ERROR IRQ1 = 0x%X\n",
966996
__func__, __LINE__, irq1);
967997
adf7242_cmd(lp, CMD_RC_PHY_RDY);
968-
adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
969-
adf7242_cmd(lp, CMD_RC_RX);
998+
adf7242_cmd_rx(lp);
970999
} else {
9711000
/* This can only be xmit without IRQ, likely a RX packet.
9721001
* we get an TX IRQ shortly - do nothing or let the xmit
9731002
* timeout handle this
9741003
*/
1004+
9751005
dev_dbg(&lp->spi->dev, "%s:%d : ERROR IRQ1 = 0x%X, xmit %d\n",
9761006
__func__, __LINE__, irq1, xmit);
1007+
adf7242_wait_status(lp, RC_STATUS_PHY_RDY,
1008+
RC_STATUS_MASK, __LINE__);
9771009
complete(&lp->tx_complete);
1010+
adf7242_clear_irqstat(lp);
9781011
}
9791012

9801013
return IRQ_HANDLED;
@@ -994,7 +1027,7 @@ static int adf7242_soft_reset(struct adf7242_local *lp, int line)
9941027
adf7242_set_promiscuous_mode(lp->hw, lp->promiscuous);
9951028
adf7242_set_csma_params(lp->hw, lp->min_be, lp->max_be,
9961029
lp->max_cca_retries);
997-
adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
1030+
adf7242_clear_irqstat(lp);
9981031

9991032
if (test_bit(FLAG_START, &lp->flags)) {
10001033
enable_irq(lp->spi->irq);
@@ -1060,7 +1093,7 @@ static int adf7242_hw_init(struct adf7242_local *lp)
10601093
adf7242_write_reg(lp, REG_IRQ1_EN0, 0);
10611094
adf7242_write_reg(lp, REG_IRQ1_EN1, IRQ_RX_PKT_RCVD | IRQ_CSMA_CA);
10621095

1063-
adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
1096+
adf7242_clear_irqstat(lp);
10641097
adf7242_write_reg(lp, REG_IRQ1_SRC0, 0xFF);
10651098

10661099
adf7242_cmd(lp, CMD_RC_IDLE);
@@ -1086,8 +1119,11 @@ static int adf7242_stats_show(struct seq_file *file, void *offset)
10861119
irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
10871120
irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
10881121

1089-
seq_printf(file, "STATUS = %X:\n%s\n%s%s%s%s%s\n", stat,
1122+
seq_printf(file, "STATUS = %X:\n%s\n%s\n%s\n%s\n%s%s%s%s%s\n", stat,
1123+
stat & STAT_SPI_READY ? "SPI_READY" : "SPI_BUSY",
1124+
stat & STAT_IRQ_STATUS ? "IRQ_PENDING" : "IRQ_CLEAR",
10901125
stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
1126+
stat & STAT_CCA_RESULT ? "CHAN_IDLE" : "CHAN_BUSY",
10911127
(stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
10921128
(stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
10931129
(stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
@@ -1257,12 +1293,14 @@ static int adf7242_remove(struct spi_device *spi)
12571293

12581294
static const struct of_device_id adf7242_of_match[] = {
12591295
{ .compatible = "adi,adf7242", },
1296+
{ .compatible = "adi,adf7241", },
12601297
{ },
12611298
};
12621299
MODULE_DEVICE_TABLE(of, adf7242_of_match);
12631300

12641301
static const struct spi_device_id adf7242_device_id[] = {
12651302
{ .name = "adf7242", },
1303+
{ .name = "adf7241", },
12661304
{ },
12671305
};
12681306
MODULE_DEVICE_TABLE(spi, adf7242_device_id);

0 commit comments

Comments
 (0)