|
19 | 19 | from ...fields.consts import * |
20 | 20 | from ...fields.public.cmis import CableLenField |
21 | 21 |
|
| 22 | +# Constants matching optoe driver |
| 23 | +CMIS_EEPROM_PAGE_SIZE = 128 |
| 24 | +CMIS_NUM_NON_BANKED_PAGES = 16 # pages 00h-0Fh |
| 25 | +CMIS_NUM_BANKED_PAGES = 240 # pages 10h-FFh |
| 26 | +CMIS_ARCH_PAGES = 256 # architectural pages per bank (matches OPTOE_ARCH_PAGES) |
| 27 | + |
22 | 28 | class CmisFlatMemMap(XcvrMemMap): |
23 | 29 | """ |
24 | 30 | Memory map for CMIS flat memory (Lower page and Upper page 0h ONLY) |
25 | 31 | """ |
26 | | - def __init__(self, codes): |
| 32 | + def __init__(self, codes, bank=0): |
| 33 | + self._bank = bank |
27 | 34 | super(CmisFlatMemMap, self).__init__(codes) |
28 | 35 |
|
29 | 36 | self.MGMT_CHARACTERISTICS = RegGroupField(consts.MGMT_CHAR_FIELD, |
@@ -138,12 +145,41 @@ def __init__(self, codes): |
138 | 145 | NumberRegField(consts.MODULE_LEVEL_CONTROL, self.getaddr(0x0, 26), size=1, ro=False), |
139 | 146 | ) |
140 | 147 |
|
| 148 | + @property |
| 149 | + def bank(self): |
| 150 | + """Returns the bank number (read-only).""" |
| 151 | + return self._bank |
| 152 | + |
141 | 153 | def getaddr(self, page, offset, page_size=128): |
142 | | - return page * page_size + offset |
| 154 | + """ |
| 155 | + Calculate linear offset for optoe driver using instance's bank. |
| 156 | +
|
| 157 | + For lower memory (page 0, offset < 128): |
| 158 | + linear_offset = offset |
| 159 | +
|
| 160 | + For paged memory: |
| 161 | + offset_in_paged_area = (page * page_size + offset) - 128 |
| 162 | + bytes_per_bank = CMIS_ARCH_PAGES * page_size (256 * 128 = 32KB) |
| 163 | + linear_offset = 128 + (bank * bytes_per_bank) + offset_in_paged_area |
| 164 | +
|
| 165 | + Simplified: |
| 166 | + linear_offset = (bank * CMIS_ARCH_PAGES + page) * page_size + offset |
| 167 | +
|
| 168 | + Note: Each bank is treated as a full 256-page (32KB) architectural block, |
| 169 | + even though only pages 10h-FFh (240 pages) are actually banked. This ensures |
| 170 | + proper alignment and matches the kernel driver behavior. |
| 171 | + """ |
| 172 | + if page == 0 and offset < 128: |
| 173 | + # Lower memory - not affected by banking |
| 174 | + return offset |
| 175 | + |
| 176 | + # For all paged memory (including bank 0), use the unified formula |
| 177 | + # that treats each bank as a 256-page (32KB) block |
| 178 | + return (self.bank * CMIS_ARCH_PAGES + page) * page_size + offset |
143 | 179 |
|
144 | 180 | class CmisMemMap(CmisFlatMemMap): |
145 | | - def __init__(self, codes): |
146 | | - super(CmisMemMap, self).__init__(codes) |
| 181 | + def __init__(self, codes, bank=0): |
| 182 | + super(CmisMemMap, self).__init__(codes, bank=bank) |
147 | 183 |
|
148 | 184 | # This memmap should contain ONLY upper page >= 01h fields |
149 | 185 | self.ADVERTISING = RegGroupField(consts.ADVERTISING_FIELD, |
@@ -227,6 +263,9 @@ def __init__(self, codes): |
227 | 263 | RegBitField(consts.VDM_SUPPORTED, 6), |
228 | 264 | RegBitField(consts.DIAG_PAGE_SUPPORT_ADVT_FIELD, 5), |
229 | 265 | ), |
| 266 | + NumberRegField(consts.BANKS_SUPPORTED_FIELD, self.getaddr(0x1, 142), |
| 267 | + *(RegBitField("Bit%d" % bit, bit) for bit in range(0, 2)) |
| 268 | + ), |
230 | 269 | NumberRegField(consts.TX_INPUT_EQ_MAX, self.getaddr(0x1, 153), |
231 | 270 | *(RegBitField("Bit%d" % (bit), bit) for bit in range (0 , 4)) |
232 | 271 | ), |
@@ -702,6 +741,3 @@ def __init__(self, codes): |
702 | 741 | ) |
703 | 742 |
|
704 | 743 | # TODO: add remaining fields |
705 | | - |
706 | | - def getaddr(self, page, offset, page_size=128): |
707 | | - return page * page_size + offset |
|
0 commit comments