| 179 | } |
| 180 | |
| 181 | static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi, |
| 182 | void *req_data) |
| 183 | { |
| 184 | struct mei_csr host; |
| 185 | unsigned ndata , n; |
| 186 | uint32_t *data; |
| 187 | |
| 188 | /* Number of dwords to write, ignoring MKHI */ |
| 189 | ndata = (mei->length) >> 2; |
| 190 | |
| 191 | /* Pad non-dword aligned request message length */ |
| 192 | if (mei->length & 3) |
| 193 | ndata++; |
| 194 | if (!ndata) { |
| 195 | printf("ME: request does not include MKHI\n"); |
| 196 | return -1; |
| 197 | } |
| 198 | ndata++; /* Add MEI header */ |
| 199 | |
| 200 | /* |
| 201 | * Make sure there is still room left in the circular buffer. |
| 202 | * Reset the buffer pointers if the requested message will not fit. |
| 203 | */ |
| 204 | read_host_csr(&host); |
| 205 | if ((host.buffer_depth - host.buffer_write_ptr) < ndata) { |
| 206 | printf("ME: circular buffer full, resetting...\n"); |
| 207 | mei_reset(); |
| 208 | read_host_csr(&host); |
| 209 | } |
| 210 | |
| 211 | /* |
| 212 | * This implementation does not handle splitting large messages |
| 213 | * across multiple transactions. Ensure the requested length |
| 214 | * will fit in the available circular buffer depth. |
| 215 | */ |
| 216 | if ((host.buffer_depth - host.buffer_write_ptr) < ndata) { |
| 217 | printf("ME: message (%u) too large for buffer (%u)\n", |
| 218 | ndata + 2, host.buffer_depth); |
| 219 | return -1; |
| 220 | } |
| 221 | |
| 222 | /* Write MEI header */ |
| 223 | mei_write_dword_ptr(mei, MEI_H_CB_WW); |
| 224 | ndata--; |
| 225 | |
| 226 | /* Write MKHI header */ |
| 227 | mei_write_dword_ptr(mkhi, MEI_H_CB_WW); |
| 228 | ndata--; |
| 229 | |
| 230 | /* Write message data */ |
| 231 | data = req_data; |
| 232 | for (n = 0; n < ndata; ++n) |
| 233 | write_cb(*data++); |
| 234 | |
| 235 | /* Generate interrupt to the ME */ |
| 236 | read_host_csr(&host); |
| 237 | host.interrupt_generate = 1; |
| 238 | write_host_csr(&host); |
no test coverage detected