1 // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause 2 3 use crate::rxops::RxOps; 4 5 #[derive(Debug, Eq, PartialEq)] 6 pub(crate) struct RxQueue { 7 /// Bitmap of rx operations. 8 queue: u8, 9 } 10 11 impl RxQueue { 12 /// New instance of RxQueue. new() -> Self13 pub fn new() -> Self { 14 RxQueue { queue: 0_u8 } 15 } 16 17 /// Enqueue a new rx operation into the queue. enqueue(&mut self, op: RxOps)18 pub fn enqueue(&mut self, op: RxOps) { 19 self.queue |= op.bitmask(); 20 } 21 22 /// Dequeue an rx operation from the queue. dequeue(&mut self) -> Option<RxOps>23 pub fn dequeue(&mut self) -> Option<RxOps> { 24 match self.peek() { 25 Some(req) => { 26 self.queue &= !req.bitmask(); 27 Some(req) 28 } 29 None => None, 30 } 31 } 32 33 /// Peek into the queue to check if it contains an rx operation. peek(&self) -> Option<RxOps>34 pub fn peek(&self) -> Option<RxOps> { 35 if self.contains(RxOps::Request.bitmask()) { 36 return Some(RxOps::Request); 37 } 38 if self.contains(RxOps::Rw.bitmask()) { 39 return Some(RxOps::Rw); 40 } 41 if self.contains(RxOps::Response.bitmask()) { 42 return Some(RxOps::Response); 43 } 44 if self.contains(RxOps::CreditUpdate.bitmask()) { 45 return Some(RxOps::CreditUpdate); 46 } 47 if self.contains(RxOps::Reset.bitmask()) { 48 Some(RxOps::Reset) 49 } else { 50 None 51 } 52 } 53 54 /// Check if the queue contains a particular rx operation. contains(&self, op: u8) -> bool55 pub fn contains(&self, op: u8) -> bool { 56 (self.queue & op) != 0 57 } 58 59 /// Check if there are any pending rx operations in the queue. pending_rx(&self) -> bool60 pub fn pending_rx(&self) -> bool { 61 self.queue != 0 62 } 63 } 64 65 #[cfg(test)] 66 mod tests { 67 use super::*; 68 69 #[test] test_contains()70 fn test_contains() { 71 let mut rxqueue = RxQueue::new(); 72 rxqueue.queue = 31; 73 74 assert!(rxqueue.contains(RxOps::Request.bitmask())); 75 assert!(rxqueue.contains(RxOps::Rw.bitmask())); 76 assert!(rxqueue.contains(RxOps::Response.bitmask())); 77 assert!(rxqueue.contains(RxOps::CreditUpdate.bitmask())); 78 assert!(rxqueue.contains(RxOps::Reset.bitmask())); 79 80 rxqueue.queue = 0; 81 assert!(!rxqueue.contains(RxOps::Request.bitmask())); 82 assert!(!rxqueue.contains(RxOps::Rw.bitmask())); 83 assert!(!rxqueue.contains(RxOps::Response.bitmask())); 84 assert!(!rxqueue.contains(RxOps::CreditUpdate.bitmask())); 85 assert!(!rxqueue.contains(RxOps::Reset.bitmask())); 86 } 87 88 #[test] test_enqueue()89 fn test_enqueue() { 90 let mut rxqueue = RxQueue::new(); 91 92 rxqueue.enqueue(RxOps::Request); 93 assert!(rxqueue.contains(RxOps::Request.bitmask())); 94 95 rxqueue.enqueue(RxOps::Rw); 96 assert!(rxqueue.contains(RxOps::Rw.bitmask())); 97 98 rxqueue.enqueue(RxOps::Response); 99 assert!(rxqueue.contains(RxOps::Response.bitmask())); 100 101 rxqueue.enqueue(RxOps::CreditUpdate); 102 assert!(rxqueue.contains(RxOps::CreditUpdate.bitmask())); 103 104 rxqueue.enqueue(RxOps::Reset); 105 assert!(rxqueue.contains(RxOps::Reset.bitmask())); 106 } 107 108 #[test] test_peek()109 fn test_peek() { 110 let mut rxqueue = RxQueue::new(); 111 112 rxqueue.queue = 31; 113 assert_eq!(rxqueue.peek(), Some(RxOps::Request)); 114 115 rxqueue.queue = 30; 116 assert_eq!(rxqueue.peek(), Some(RxOps::Rw)); 117 118 rxqueue.queue = 28; 119 assert_eq!(rxqueue.peek(), Some(RxOps::Response)); 120 121 rxqueue.queue = 24; 122 assert_eq!(rxqueue.peek(), Some(RxOps::CreditUpdate)); 123 124 rxqueue.queue = 16; 125 assert_eq!(rxqueue.peek(), Some(RxOps::Reset)); 126 } 127 128 #[test] test_dequeue()129 fn test_dequeue() { 130 let mut rxqueue = RxQueue::new(); 131 rxqueue.queue = 31; 132 133 assert_eq!(rxqueue.dequeue(), Some(RxOps::Request)); 134 assert!(!rxqueue.contains(RxOps::Request.bitmask())); 135 136 assert_eq!(rxqueue.dequeue(), Some(RxOps::Rw)); 137 assert!(!rxqueue.contains(RxOps::Rw.bitmask())); 138 139 assert_eq!(rxqueue.dequeue(), Some(RxOps::Response)); 140 assert!(!rxqueue.contains(RxOps::Response.bitmask())); 141 142 assert_eq!(rxqueue.dequeue(), Some(RxOps::CreditUpdate)); 143 assert!(!rxqueue.contains(RxOps::CreditUpdate.bitmask())); 144 145 assert_eq!(rxqueue.dequeue(), Some(RxOps::Reset)); 146 assert!(!rxqueue.contains(RxOps::Reset.bitmask())); 147 } 148 149 #[test] test_pending_rx()150 fn test_pending_rx() { 151 let mut rxqueue = RxQueue::new(); 152 assert!(!rxqueue.pending_rx()); 153 154 rxqueue.queue = 1; 155 assert!(rxqueue.pending_rx()); 156 } 157 } 158