Pārlūkot izejas kodu

Time out on chunked extended messages

Now when a part of a chunked extended message is received, the
ChunkingNotSupportedTimer is run.  When it times out, we transition to
PE_SNK_Send_Not_Supported.  Just like the spec says.
Clara Hobbs 7 gadus atpakaļ
vecāks
revīzija
f62ca97cc6
3 mainītis faili ar 75 papildinājumiem un 3 dzēšanām
  1. 30
    0
      lib/include/pd.h
  2. 8
    2
      lib/include/pdb_msg.h
  3. 37
    1
      lib/src/policy_engine.c

+ 30
- 0
lib/include/pd.h Parādīt failu

@@ -114,6 +114,27 @@
114 114
 #define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT)
115 115
 
116 116
 
117
+/*
118
+ * PD Extended Message Header
119
+ */
120
+#define PD_EXTHDR_DATA_SIZE_SHIFT 0
121
+#define PD_EXTHDR_DATA_SIZE (0x1FF << PD_EXTHDR_DATA_SIZE_SHIFT)
122
+#define PD_EXTHDR_REQUEST_CHUNK_SHIFT 10
123
+#define PD_EXTHDR_REQUEST_CHUNK (1 << PD_EXTHDR_REQUEST_CHUNK_SHIFT)
124
+#define PD_EXTHDR_CHUNK_NUMBER_SHIFT 11
125
+#define PD_EXTHDR_CHUNK_NUMBER (0xF << PD_EXTHDR_CHUNK_NUMBER_SHIFT)
126
+#define PD_EXTHDR_CHUNKED_SHIFT 15
127
+#define PD_EXTHDR_CHUNKED (1 << PD_EXTHDR_CHUNKED_SHIFT)
128
+
129
+/* Data size */
130
+#define PD_DATA_SIZE(n) (((n) << PD_EXTHDR_DATA_SIZE_SHIFT) & PD_EXTHDR_DATA_SIZE)
131
+#define PD_DATA_SIZE_GET(msg) (((msg)->exthdr & PD_EXTHDR_DATA_SIZE) >> PD_EXTHDR_DATA_SIZE_SHIFT)
132
+
133
+/* Chunk number */
134
+#define PD_CHUNK_NUMBER(n) (((n) << PD_EXTHDR_CHUNK_NUMBER_SHIFT) & PD_EXTHDR_CHUNK_NUMBER)
135
+#define PD_CHUNK_NUMBER_GET(msg) (((msg)->exthdr & PD_EXTHDR_CHUNK_NUMBER) >> PD_EXTHDR_CHUNK_NUMBER_SHIFT)
136
+
137
+
117 138
 /*
118 139
  * PD Power Data Object
119 140
  */
@@ -216,6 +237,7 @@
216 237
  * Where a range is specified, the middle of the range (rounded down to the
217 238
  * nearest millisecond) is used.
218 239
  */
240
+#define PD_T_CHUNKING_NOT_SUPPORTED MS2ST(45)
219 241
 #define PD_T_HARD_RESET_COMPLETE MS2ST(4)
220 242
 #define PD_T_PS_TRANSITION MS2ST(500)
221 243
 #define PD_T_SENDER_RESPONSE MS2ST(27)
@@ -231,6 +253,14 @@
231 253
 #define PD_N_HARD_RESET_COUNT 2
232 254
 
233 255
 
256
+/*
257
+ * Value parameters
258
+ */
259
+#define PD_MAX_EXT_MSG_LEN 260
260
+#define PD_MAX_EXT_MSG_CHUNK_LEN 26
261
+#define PD_MAX_EXT_MSG_LEGACY_LEN 26
262
+
263
+
234 264
 /*
235 265
  * Unit conversions
236 266
  *

+ 8
- 2
lib/include/pdb_msg.h Parādīt failu

@@ -27,7 +27,7 @@
27 27
 /*
28 28
  * PD message union
29 29
  *
30
- * This can be safely read from or written to in either form without any
30
+ * This can be safely read from or written to in any form without any
31 31
  * transformations because everything in the system is little-endian.
32 32
  *
33 33
  * Two bytes of padding are required at the start to prevent problems due to
@@ -42,7 +42,13 @@ union pd_msg {
42 42
     struct {
43 43
         uint8_t _pad2[2];
44 44
         uint16_t hdr;
45
-        uint32_t obj[7];
45
+        union {
46
+            uint32_t obj[7];
47
+            struct {
48
+                uint16_t exthdr;
49
+                uint8_t data[26];
50
+            };
51
+        };
46 52
     } __attribute__((packed));
47 53
 };
48 54
 

+ 37
- 1
lib/src/policy_engine.c Parādīt failu

@@ -42,6 +42,7 @@ enum policy_engine_state {
42 42
     PESinkSoftReset,
43 43
     PESinkSendSoftReset,
44 44
     PESinkSendNotSupported,
45
+    PESinkChunkReceived,
45 46
     PESinkSourceUnresponsive
46 47
 };
47 48
 
@@ -404,7 +405,24 @@ static enum policy_engine_state pe_sink_ready(struct pdb_config *cfg)
404 405
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
405 406
                 cfg->pe._message = NULL;
406 407
                 return PESinkSoftReset;
407
-            /* If we got an unknown message, send a soft reset */
408
+            /* PD 3.0 messges */
409
+            } else if ((cfg->pe.hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
410
+                /* If the message is a multi-chunk extended message, let it
411
+                 * time out. */
412
+                if ((cfg->pe._message->hdr & PD_HDR_EXT)
413
+                        && (PD_DATA_SIZE_GET(cfg->pe._message) > PD_MAX_EXT_MSG_LEGACY_LEN)) {
414
+                    chPoolFree(&pdb_msg_pool, cfg->pe._message);
415
+                    cfg->pe._message = NULL;
416
+                    return PESinkChunkReceived;
417
+                /* If we got an unknown message, send a soft reset */
418
+                } else {
419
+                    chPoolFree(&pdb_msg_pool, cfg->pe._message);
420
+                    cfg->pe._message = NULL;
421
+                    return PESinkSendSoftReset;
422
+                }
423
+            /* If we got an unknown message, send a soft reset
424
+             *
425
+             * XXX I don't like that this is duplicated. */
408 426
             } else {
409 427
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
410 428
                 cfg->pe._message = NULL;
@@ -633,6 +651,21 @@ static enum policy_engine_state pe_sink_send_not_supported(struct pdb_config *cf
633 651
     return PESinkReady;
634 652
 }
635 653
 
654
+static enum policy_engine_state pe_sink_chunk_received(struct pdb_config *cfg)
655
+{
656
+    (void) cfg;
657
+
658
+    /* Wait for tChunkingNotSupported */
659
+    eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_RESET,
660
+            PD_T_CHUNKING_NOT_SUPPORTED);
661
+    /* If we got reset signaling, transition to default */
662
+    if (evt & PDB_EVT_PE_RESET) {
663
+        return PESinkTransitionDefault;
664
+    }
665
+
666
+    return PESinkSendNotSupported;
667
+}
668
+
636 669
 /*
637 670
  * When Power Delivery is unresponsive, fall back to Type-C Current
638 671
  */
@@ -717,6 +750,9 @@ static THD_FUNCTION(PolicyEngine, vcfg) {
717 750
             case PESinkSendNotSupported:
718 751
                 state = pe_sink_send_not_supported(cfg);
719 752
                 break;
753
+            case PESinkChunkReceived:
754
+                state = pe_sink_chunk_received(cfg);
755
+                break;
720 756
             case PESinkSourceUnresponsive:
721 757
                 state = pe_sink_source_unresponsive(cfg);
722 758
                 break;

Notiek ielāde…
Atcelt
Saglabāt