aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Luick <dean.luick@intel.com>2015-11-16 21:59:35 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-21 16:45:38 -0500
commitcd371e0959a3f2d5df69d50000750f7eefc94659 (patch)
tree61d2494139a11d7ab753d04df35ff11f5188556a
parent5d9157aafb16bed45e3bf167baa16f1fbe1090cd (diff)
staging/rdma/hfi1: Adjust EPROM partitions, add EPROM commands
Add a new EPROM partition, adjusting partition placement. Add EPROM range commands as a supserset of the partition commands. Remove old partition commands. Enhance EPROM erase, creating a range function and using the largest erase (sub) commands when possible. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Dean Luick <dean.luick@intel.com> Signed-off-by: Jubin John <jubin.john@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/rdma/hfi1/eprom.c119
-rw-r--r--drivers/staging/rdma/hfi1/file_ops.c18
-rw-r--r--include/uapi/rdma/hfi/hfi1_user.h10
3 files changed, 77 insertions, 70 deletions
diff --git a/drivers/staging/rdma/hfi1/eprom.c b/drivers/staging/rdma/hfi1/eprom.c
index b61d3ae93ed1..fb620c97f592 100644
--- a/drivers/staging/rdma/hfi1/eprom.c
+++ b/drivers/staging/rdma/hfi1/eprom.c
@@ -53,17 +53,26 @@
53#include "eprom.h" 53#include "eprom.h"
54 54
55/* 55/*
56 * The EPROM is logically divided into two partitions: 56 * The EPROM is logically divided into three partitions:
57 * partition 0: the first 128K, visible from PCI ROM BAR 57 * partition 0: the first 128K, visible from PCI ROM BAR
58 * partition 1: the rest 58 * partition 1: 4K config file (sector size)
59 * partition 2: the rest
59 */ 60 */
60#define P0_SIZE (128 * 1024) 61#define P0_SIZE (128 * 1024)
62#define P1_SIZE (4 * 1024)
61#define P1_START P0_SIZE 63#define P1_START P0_SIZE
64#define P2_START (P0_SIZE + P1_SIZE)
65
66/* erase sizes supported by the controller */
67#define SIZE_4KB (4 * 1024)
68#define MASK_4KB (SIZE_4KB - 1)
62 69
63/* largest erase size supported by the controller */
64#define SIZE_32KB (32 * 1024) 70#define SIZE_32KB (32 * 1024)
65#define MASK_32KB (SIZE_32KB - 1) 71#define MASK_32KB (SIZE_32KB - 1)
66 72
73#define SIZE_64KB (64 * 1024)
74#define MASK_64KB (SIZE_64KB - 1)
75
67/* controller page size, in bytes */ 76/* controller page size, in bytes */
68#define EP_PAGE_SIZE 256 77#define EP_PAGE_SIZE 256
69#define EEP_PAGE_MASK (EP_PAGE_SIZE - 1) 78#define EEP_PAGE_MASK (EP_PAGE_SIZE - 1)
@@ -75,10 +84,12 @@
75#define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr) 84#define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr)
76#define CMD_READ_SR1 ((0x05 << CMD_SHIFT)) 85#define CMD_READ_SR1 ((0x05 << CMD_SHIFT))
77#define CMD_WRITE_ENABLE ((0x06 << CMD_SHIFT)) 86#define CMD_WRITE_ENABLE ((0x06 << CMD_SHIFT))
87#define CMD_SECTOR_ERASE_4KB(addr) ((0x20 << CMD_SHIFT) | addr)
78#define CMD_SECTOR_ERASE_32KB(addr) ((0x52 << CMD_SHIFT) | addr) 88#define CMD_SECTOR_ERASE_32KB(addr) ((0x52 << CMD_SHIFT) | addr)
79#define CMD_CHIP_ERASE ((0x60 << CMD_SHIFT)) 89#define CMD_CHIP_ERASE ((0x60 << CMD_SHIFT))
80#define CMD_READ_MANUF_DEV_ID ((0x90 << CMD_SHIFT)) 90#define CMD_READ_MANUF_DEV_ID ((0x90 << CMD_SHIFT))
81#define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT)) 91#define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT))
92#define CMD_SECTOR_ERASE_64KB(addr) ((0xd8 << CMD_SHIFT) | addr)
82 93
83/* controller interface speeds */ 94/* controller interface speeds */
84#define EP_SPEED_FULL 0x2 /* full speed */ 95#define EP_SPEED_FULL 0x2 /* full speed */
@@ -188,28 +199,43 @@ static int erase_chip(struct hfi1_devdata *dd)
188} 199}
189 200
190/* 201/*
191 * Erase a range using the 32KB erase command. 202 * Erase a range.
192 */ 203 */
193static int erase_32kb_range(struct hfi1_devdata *dd, u32 start, u32 end) 204static int erase_range(struct hfi1_devdata *dd, u32 start, u32 len)
194{ 205{
206 u32 end = start + len;
195 int ret = 0; 207 int ret = 0;
196 208
197 if (end < start) 209 if (end < start)
198 return -EINVAL; 210 return -EINVAL;
199 211
200 if ((start & MASK_32KB) || (end & MASK_32KB)) { 212 /* check the end points for the minimum erase */
213 if ((start & MASK_4KB) || (end & MASK_4KB)) {
201 dd_dev_err(dd, 214 dd_dev_err(dd,
202 "%s: non-aligned range (0x%x,0x%x) for a 32KB erase\n", 215 "%s: non-aligned range (0x%x,0x%x) for a 4KB erase\n",
203 __func__, start, end); 216 __func__, start, end);
204 return -EINVAL; 217 return -EINVAL;
205 } 218 }
206 219
207 write_enable(dd); 220 write_enable(dd);
208 221
209 for (; start < end; start += SIZE_32KB) { 222 while (start < end) {
210 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE); 223 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE);
211 write_csr(dd, ASIC_EEP_ADDR_CMD, 224 /* check in order of largest to smallest */
212 CMD_SECTOR_ERASE_32KB(start)); 225 if (((start & MASK_64KB) == 0) && (start + SIZE_64KB <= end)) {
226 write_csr(dd, ASIC_EEP_ADDR_CMD,
227 CMD_SECTOR_ERASE_64KB(start));
228 start += SIZE_64KB;
229 } else if (((start & MASK_32KB) == 0) &&
230 (start + SIZE_32KB <= end)) {
231 write_csr(dd, ASIC_EEP_ADDR_CMD,
232 CMD_SECTOR_ERASE_32KB(start));
233 start += SIZE_32KB;
234 } else { /* 4KB will work */
235 write_csr(dd, ASIC_EEP_ADDR_CMD,
236 CMD_SECTOR_ERASE_4KB(start));
237 start += SIZE_4KB;
238 }
213 ret = wait_for_not_busy(dd); 239 ret = wait_for_not_busy(dd);
214 if (ret) 240 if (ret)
215 goto done; 241 goto done;
@@ -309,6 +335,18 @@ done:
309 return ret; 335 return ret;
310} 336}
311 337
338/* convert an range composite to a length, in bytes */
339static inline u32 extract_rlen(u32 composite)
340{
341 return (composite & 0xffff) * EP_PAGE_SIZE;
342}
343
344/* convert an range composite to a start, in bytes */
345static inline u32 extract_rstart(u32 composite)
346{
347 return (composite >> 16) * EP_PAGE_SIZE;
348}
349
312/* 350/*
313 * Perform the given operation on the EPROM. Called from user space. The 351 * Perform the given operation on the EPROM. Called from user space. The
314 * user credentials have already been checked. 352 * user credentials have already been checked.
@@ -319,6 +357,8 @@ int handle_eprom_command(const struct hfi1_cmd *cmd)
319{ 357{
320 struct hfi1_devdata *dd; 358 struct hfi1_devdata *dd;
321 u32 dev_id; 359 u32 dev_id;
360 u32 rlen; /* range length */
361 u32 rstart; /* range start */
322 int ret = 0; 362 int ret = 0;
323 363
324 /* 364 /*
@@ -364,54 +404,29 @@ int handle_eprom_command(const struct hfi1_cmd *cmd)
364 sizeof(u32))) 404 sizeof(u32)))
365 ret = -EFAULT; 405 ret = -EFAULT;
366 break; 406 break;
407
367 case HFI1_CMD_EP_ERASE_CHIP: 408 case HFI1_CMD_EP_ERASE_CHIP:
368 ret = erase_chip(dd); 409 ret = erase_chip(dd);
369 break; 410 break;
370 case HFI1_CMD_EP_ERASE_P0: 411
371 if (cmd->len != P0_SIZE) { 412 case HFI1_CMD_EP_ERASE_RANGE:
372 ret = -ERANGE; 413 rlen = extract_rlen(cmd->len);
373 break; 414 rstart = extract_rstart(cmd->len);
374 } 415 ret = erase_range(dd, rstart, rlen);
375 ret = erase_32kb_range(dd, 0, cmd->len);
376 break;
377 case HFI1_CMD_EP_ERASE_P1:
378 /* check for overflow */
379 if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) {
380 ret = -ERANGE;
381 break;
382 }
383 ret = erase_32kb_range(dd, P1_START, P1_START + cmd->len);
384 break;
385 case HFI1_CMD_EP_READ_P0:
386 if (cmd->len != P0_SIZE) {
387 ret = -ERANGE;
388 break;
389 }
390 ret = read_length(dd, 0, cmd->len, cmd->addr);
391 break;
392 case HFI1_CMD_EP_READ_P1:
393 /* check for overflow */
394 if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) {
395 ret = -ERANGE;
396 break;
397 }
398 ret = read_length(dd, P1_START, cmd->len, cmd->addr);
399 break; 416 break;
400 case HFI1_CMD_EP_WRITE_P0: 417
401 if (cmd->len > P0_SIZE) { 418 case HFI1_CMD_EP_READ_RANGE:
402 ret = -ERANGE; 419 rlen = extract_rlen(cmd->len);
403 break; 420 rstart = extract_rstart(cmd->len);
404 } 421 ret = read_length(dd, rstart, rlen, cmd->addr);
405 ret = write_length(dd, 0, cmd->len, cmd->addr);
406 break; 422 break;
407 case HFI1_CMD_EP_WRITE_P1: 423
408 /* check for overflow */ 424 case HFI1_CMD_EP_WRITE_RANGE:
409 if (P1_START + cmd->len > ASIC_EEP_ADDR_CMD_EP_ADDR_MASK) { 425 rlen = extract_rlen(cmd->len);
410 ret = -ERANGE; 426 rstart = extract_rstart(cmd->len);
411 break; 427 ret = write_length(dd, rstart, rlen, cmd->addr);
412 }
413 ret = write_length(dd, P1_START, cmd->len, cmd->addr);
414 break; 428 break;
429
415 default: 430 default:
416 dd_dev_err(dd, "%s: unexpected command %d\n", 431 dd_dev_err(dd, "%s: unexpected command %d\n",
417 __func__, cmd->type); 432 __func__, cmd->type);
diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c
index 22037ce984c8..874305f0a925 100644
--- a/drivers/staging/rdma/hfi1/file_ops.c
+++ b/drivers/staging/rdma/hfi1/file_ops.c
@@ -234,12 +234,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
234 break; 234 break;
235 case HFI1_CMD_EP_INFO: 235 case HFI1_CMD_EP_INFO:
236 case HFI1_CMD_EP_ERASE_CHIP: 236 case HFI1_CMD_EP_ERASE_CHIP:
237 case HFI1_CMD_EP_ERASE_P0: 237 case HFI1_CMD_EP_ERASE_RANGE:
238 case HFI1_CMD_EP_ERASE_P1: 238 case HFI1_CMD_EP_READ_RANGE:
239 case HFI1_CMD_EP_READ_P0: 239 case HFI1_CMD_EP_WRITE_RANGE:
240 case HFI1_CMD_EP_READ_P1:
241 case HFI1_CMD_EP_WRITE_P0:
242 case HFI1_CMD_EP_WRITE_P1:
243 uctxt_required = 0; /* assigned user context not required */ 240 uctxt_required = 0; /* assigned user context not required */
244 must_be_root = 1; /* validate user */ 241 must_be_root = 1; /* validate user */
245 copy = 0; 242 copy = 0;
@@ -393,12 +390,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
393 } 390 }
394 case HFI1_CMD_EP_INFO: 391 case HFI1_CMD_EP_INFO:
395 case HFI1_CMD_EP_ERASE_CHIP: 392 case HFI1_CMD_EP_ERASE_CHIP:
396 case HFI1_CMD_EP_ERASE_P0: 393 case HFI1_CMD_EP_ERASE_RANGE:
397 case HFI1_CMD_EP_ERASE_P1: 394 case HFI1_CMD_EP_READ_RANGE:
398 case HFI1_CMD_EP_READ_P0: 395 case HFI1_CMD_EP_WRITE_RANGE:
399 case HFI1_CMD_EP_READ_P1:
400 case HFI1_CMD_EP_WRITE_P0:
401 case HFI1_CMD_EP_WRITE_P1:
402 ret = handle_eprom_command(&cmd); 396 ret = handle_eprom_command(&cmd);
403 break; 397 break;
404 } 398 }
diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h
index a2fc6cbfe414..288694e422fb 100644
--- a/include/uapi/rdma/hfi/hfi1_user.h
+++ b/include/uapi/rdma/hfi/hfi1_user.h
@@ -137,12 +137,10 @@
137/* separate EPROM commands from normal PSM commands */ 137/* separate EPROM commands from normal PSM commands */
138#define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ 138#define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */
139#define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ 139#define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */
140#define HFI1_CMD_EP_ERASE_P0 66 /* erase EPROM partition 0 */ 140/* range 66-74 no longer used */
141#define HFI1_CMD_EP_ERASE_P1 67 /* erase EPROM partition 1 */ 141#define HFI1_CMD_EP_ERASE_RANGE 75 /* erase EPROM range */
142#define HFI1_CMD_EP_READ_P0 68 /* read EPROM partition 0 */ 142#define HFI1_CMD_EP_READ_RANGE 76 /* read EPROM range */
143#define HFI1_CMD_EP_READ_P1 69 /* read EPROM partition 1 */ 143#define HFI1_CMD_EP_WRITE_RANGE 77 /* write EPROM range */
144#define HFI1_CMD_EP_WRITE_P0 70 /* write EPROM partition 0 */
145#define HFI1_CMD_EP_WRITE_P1 71 /* write EPROM partition 1 */
146 144
147#define _HFI1_EVENT_FROZEN_BIT 0 145#define _HFI1_EVENT_FROZEN_BIT 0
148#define _HFI1_EVENT_LINKDOWN_BIT 1 146#define _HFI1_EVENT_LINKDOWN_BIT 1