forked from TencentOS/TencentOS-kernel
Compare commits
3 Commits
tk3/master
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
6bd26b3101 | |
|
|
a88d1328fa | |
|
|
33347536c7 |
|
|
@ -903,7 +903,7 @@ static int ubd_disk_register(int major, u64 size, int unit,
|
||||||
|
|
||||||
disk->private_data = &ubd_devs[unit];
|
disk->private_data = &ubd_devs[unit];
|
||||||
disk->queue = ubd_devs[unit].queue;
|
disk->queue = ubd_devs[unit].queue;
|
||||||
device_add_disk(parent, disk, NULL);
|
device_add_disk(parent, disk);
|
||||||
|
|
||||||
*disk_out = disk;
|
*disk_out = disk;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -835,9 +835,6 @@ static void blk_rq_timed_out_timer(unsigned long data)
|
||||||
{
|
{
|
||||||
struct request_queue *q = (struct request_queue *)data;
|
struct request_queue *q = (struct request_queue *)data;
|
||||||
|
|
||||||
if (blk_queue_no_timeout(q))
|
|
||||||
return;
|
|
||||||
|
|
||||||
kblockd_schedule_work(&q->timeout_work);
|
kblockd_schedule_work(&q->timeout_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2439,9 +2439,6 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
|
||||||
|
|
||||||
q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
|
q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
|
||||||
|
|
||||||
if (set->flags & BLK_MQ_F_NO_TIMEOUT)
|
|
||||||
queue_flag_set_unlocked(QUEUE_FLAG_NO_TIMEOUT, q);
|
|
||||||
|
|
||||||
if (!(set->flags & BLK_MQ_F_SG_MERGE))
|
if (!(set->flags & BLK_MQ_F_SG_MERGE))
|
||||||
q->queue_flags |= 1 << QUEUE_FLAG_NO_SG_MERGE;
|
q->queue_flags |= 1 << QUEUE_FLAG_NO_SG_MERGE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,14 +162,6 @@ static ssize_t queue_io_min_show(struct request_queue *q, char *page)
|
||||||
return queue_var_show(queue_io_min(q), page);
|
return queue_var_show(queue_io_min(q), page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t queue_timeout_timer_pending_show(struct request_queue *q, char *page)
|
|
||||||
{
|
|
||||||
unsigned long pending;
|
|
||||||
|
|
||||||
pending = timer_pending(&q->timeout);
|
|
||||||
return queue_var_show(pending, page);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
|
static ssize_t queue_io_opt_show(struct request_queue *q, char *page)
|
||||||
{
|
{
|
||||||
return queue_var_show(queue_io_opt(q), page);
|
return queue_var_show(queue_io_opt(q), page);
|
||||||
|
|
@ -598,11 +590,6 @@ static struct queue_sysfs_entry queue_io_min_entry = {
|
||||||
.show = queue_io_min_show,
|
.show = queue_io_min_show,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct queue_sysfs_entry queue_timeout_timer_pending = {
|
|
||||||
.attr = {.name = "timeout_timer_pending", .mode = S_IRUGO },
|
|
||||||
.show = queue_timeout_timer_pending_show,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct queue_sysfs_entry queue_io_opt_entry = {
|
static struct queue_sysfs_entry queue_io_opt_entry = {
|
||||||
.attr = {.name = "optimal_io_size", .mode = S_IRUGO },
|
.attr = {.name = "optimal_io_size", .mode = S_IRUGO },
|
||||||
.show = queue_io_opt_show,
|
.show = queue_io_opt_show,
|
||||||
|
|
@ -727,7 +714,6 @@ static struct attribute *default_attrs[] = {
|
||||||
&queue_physical_block_size_entry.attr,
|
&queue_physical_block_size_entry.attr,
|
||||||
&queue_chunk_sectors_entry.attr,
|
&queue_chunk_sectors_entry.attr,
|
||||||
&queue_io_min_entry.attr,
|
&queue_io_min_entry.attr,
|
||||||
&queue_timeout_timer_pending.attr,
|
|
||||||
&queue_io_opt_entry.attr,
|
&queue_io_opt_entry.attr,
|
||||||
&queue_discard_granularity_entry.attr,
|
&queue_discard_granularity_entry.attr,
|
||||||
&queue_discard_max_entry.attr,
|
&queue_discard_max_entry.attr,
|
||||||
|
|
|
||||||
|
|
@ -199,9 +199,6 @@ void blk_add_timer(struct request *req)
|
||||||
if (!q->mq_ops && !q->rq_timed_out_fn)
|
if (!q->mq_ops && !q->rq_timed_out_fn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (blk_queue_no_timeout(q))
|
|
||||||
return;
|
|
||||||
|
|
||||||
BUG_ON(!list_empty(&req->timeout_list));
|
BUG_ON(!list_empty(&req->timeout_list));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -564,8 +564,7 @@ static int exact_lock(dev_t devt, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_disk(struct device *parent, struct gendisk *disk,
|
static void register_disk(struct device *parent, struct gendisk *disk)
|
||||||
const struct attribute_group **groups)
|
|
||||||
{
|
{
|
||||||
struct device *ddev = disk_to_dev(disk);
|
struct device *ddev = disk_to_dev(disk);
|
||||||
struct block_device *bdev;
|
struct block_device *bdev;
|
||||||
|
|
@ -580,10 +579,6 @@ static void register_disk(struct device *parent, struct gendisk *disk,
|
||||||
/* delay uevents, until we scanned partition table */
|
/* delay uevents, until we scanned partition table */
|
||||||
dev_set_uevent_suppress(ddev, 1);
|
dev_set_uevent_suppress(ddev, 1);
|
||||||
|
|
||||||
if (groups) {
|
|
||||||
WARN_ON(ddev->groups);
|
|
||||||
ddev->groups = groups;
|
|
||||||
}
|
|
||||||
if (device_add(ddev))
|
if (device_add(ddev))
|
||||||
return;
|
return;
|
||||||
if (!sysfs_deprecated) {
|
if (!sysfs_deprecated) {
|
||||||
|
|
@ -645,8 +640,7 @@ exit:
|
||||||
*
|
*
|
||||||
* FIXME: error handling
|
* FIXME: error handling
|
||||||
*/
|
*/
|
||||||
void device_add_disk(struct device *parent, struct gendisk *disk,
|
void device_add_disk(struct device *parent, struct gendisk *disk)
|
||||||
const struct attribute_group **groups)
|
|
||||||
{
|
{
|
||||||
struct backing_dev_info *bdi;
|
struct backing_dev_info *bdi;
|
||||||
dev_t devt;
|
dev_t devt;
|
||||||
|
|
@ -682,7 +676,7 @@ void device_add_disk(struct device *parent, struct gendisk *disk,
|
||||||
|
|
||||||
blk_register_region(disk_devt(disk), disk->minors, NULL,
|
blk_register_region(disk_devt(disk), disk->minors, NULL,
|
||||||
exact_match, exact_lock, disk);
|
exact_match, exact_lock, disk);
|
||||||
register_disk(parent, disk, groups);
|
register_disk(parent, disk);
|
||||||
blk_register_queue(disk);
|
blk_register_queue(disk);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,7 @@ int aoeblk_init(void);
|
||||||
void aoeblk_exit(void);
|
void aoeblk_exit(void);
|
||||||
void aoeblk_gdalloc(void *);
|
void aoeblk_gdalloc(void *);
|
||||||
void aoedisk_rm_debugfs(struct aoedev *d);
|
void aoedisk_rm_debugfs(struct aoedev *d);
|
||||||
|
void aoedisk_rm_sysfs(struct aoedev *d);
|
||||||
|
|
||||||
int aoechr_init(void);
|
int aoechr_init(void);
|
||||||
void aoechr_exit(void);
|
void aoechr_exit(void);
|
||||||
|
|
|
||||||
|
|
@ -177,15 +177,10 @@ static struct attribute *aoe_attrs[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct attribute_group aoe_attr_group = {
|
static const struct attribute_group attr_group = {
|
||||||
.attrs = aoe_attrs,
|
.attrs = aoe_attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct attribute_group *aoe_attr_groups[] = {
|
|
||||||
&aoe_attr_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct file_operations aoe_debugfs_fops = {
|
static const struct file_operations aoe_debugfs_fops = {
|
||||||
.open = aoe_debugfs_open,
|
.open = aoe_debugfs_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
|
|
@ -224,6 +219,17 @@ aoedisk_rm_debugfs(struct aoedev *d)
|
||||||
d->debugfs = NULL;
|
d->debugfs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
aoedisk_add_sysfs(struct aoedev *d)
|
||||||
|
{
|
||||||
|
return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
aoedisk_rm_sysfs(struct aoedev *d)
|
||||||
|
{
|
||||||
|
sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
aoeblk_open(struct block_device *bdev, fmode_t mode)
|
aoeblk_open(struct block_device *bdev, fmode_t mode)
|
||||||
{
|
{
|
||||||
|
|
@ -412,7 +418,8 @@ aoeblk_gdalloc(void *vp)
|
||||||
|
|
||||||
spin_unlock_irqrestore(&d->lock, flags);
|
spin_unlock_irqrestore(&d->lock, flags);
|
||||||
|
|
||||||
device_add_disk(NULL, gd, aoe_attr_groups);
|
add_disk(gd);
|
||||||
|
aoedisk_add_sysfs(d);
|
||||||
aoedisk_add_debugfs(d);
|
aoedisk_add_debugfs(d);
|
||||||
|
|
||||||
spin_lock_irqsave(&d->lock, flags);
|
spin_lock_irqsave(&d->lock, flags);
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,7 @@ freedev(struct aoedev *d)
|
||||||
del_timer_sync(&d->timer);
|
del_timer_sync(&d->timer);
|
||||||
if (d->gd) {
|
if (d->gd) {
|
||||||
aoedisk_rm_debugfs(d);
|
aoedisk_rm_debugfs(d);
|
||||||
|
aoedisk_rm_sysfs(d);
|
||||||
del_gendisk(d->gd);
|
del_gendisk(d->gd);
|
||||||
put_disk(d->gd);
|
put_disk(d->gd);
|
||||||
blk_cleanup_queue(d->blkq);
|
blk_cleanup_queue(d->blkq);
|
||||||
|
|
|
||||||
|
|
@ -4675,7 +4675,7 @@ static int __init do_floppy_init(void)
|
||||||
/* to be cleaned up... */
|
/* to be cleaned up... */
|
||||||
disks[drive]->private_data = (void *)(long)drive;
|
disks[drive]->private_data = (void *)(long)drive;
|
||||||
disks[drive]->flags |= GENHD_FL_REMOVABLE;
|
disks[drive]->flags |= GENHD_FL_REMOVABLE;
|
||||||
device_add_disk(&floppy_device[drive].dev, disks[drive], NULL);
|
device_add_disk(&floppy_device[drive].dev, disks[drive]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -3889,7 +3889,7 @@ skip_create_disk:
|
||||||
set_capacity(dd->disk, capacity);
|
set_capacity(dd->disk, capacity);
|
||||||
|
|
||||||
/* Enable the block device and add it to /dev */
|
/* Enable the block device and add it to /dev */
|
||||||
device_add_disk(&dd->pdev->dev, dd->disk, NULL);
|
device_add_disk(&dd->pdev->dev, dd->disk);
|
||||||
|
|
||||||
dd->bdev = bdget_disk(dd->disk, 0);
|
dd->bdev = bdget_disk(dd->disk, 0);
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -502,7 +502,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
|
||||||
gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
|
gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
|
||||||
get_capacity(gendisk) >> 11);
|
get_capacity(gendisk) >> 11);
|
||||||
|
|
||||||
device_add_disk(&dev->sbd.core, gendisk, NULL);
|
device_add_disk(&dev->sbd.core, gendisk);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_cleanup_queue:
|
fail_cleanup_queue:
|
||||||
|
|
|
||||||
|
|
@ -781,7 +781,7 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev)
|
||||||
dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n",
|
dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n",
|
||||||
gendisk->disk_name, get_capacity(gendisk) >> 11);
|
gendisk->disk_name, get_capacity(gendisk) >> 11);
|
||||||
|
|
||||||
device_add_disk(&dev->core, gendisk, NULL);
|
device_add_disk(&dev->core, gendisk);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_cleanup_queue:
|
fail_cleanup_queue:
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ int rsxx_attach_dev(struct rsxx_cardinfo *card)
|
||||||
set_capacity(card->gendisk, card->size8 >> 9);
|
set_capacity(card->gendisk, card->size8 >> 9);
|
||||||
else
|
else
|
||||||
set_capacity(card->gendisk, 0);
|
set_capacity(card->gendisk, 0);
|
||||||
device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL);
|
device_add_disk(CARD_TO_DEV(card), card->gendisk);
|
||||||
card->bdev_attached = 1;
|
card->bdev_attached = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3102,7 +3102,7 @@ static int skd_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||||
static int skd_bdev_attach(struct device *parent, struct skd_device *skdev)
|
static int skd_bdev_attach(struct device *parent, struct skd_device *skdev)
|
||||||
{
|
{
|
||||||
dev_dbg(&skdev->pdev->dev, "add_disk\n");
|
dev_dbg(&skdev->pdev->dev, "add_disk\n");
|
||||||
device_add_disk(parent, skdev->disk, NULL);
|
device_add_disk(parent, skdev->disk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -855,7 +855,7 @@ static int probe_disk(struct vdc_port *port)
|
||||||
port->vdisk_size, (port->vdisk_size >> (20 - 9)),
|
port->vdisk_size, (port->vdisk_size >> (20 - 9)),
|
||||||
port->vio.ver.major, port->vio.ver.minor);
|
port->vio.ver.major, port->vio.ver.minor);
|
||||||
|
|
||||||
device_add_disk(&port->vio.vdev->dev, g, NULL);
|
device_add_disk(&port->vio.vdev->dev, g);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -351,8 +351,8 @@ static int minor_to_index(int minor)
|
||||||
return minor >> PART_BITS;
|
return minor >> PART_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t serial_show(struct device *dev,
|
static ssize_t virtblk_serial_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct gendisk *disk = dev_to_disk(dev);
|
struct gendisk *disk = dev_to_disk(dev);
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -371,7 +371,7 @@ static ssize_t serial_show(struct device *dev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR_RO(serial);
|
static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
|
||||||
|
|
||||||
static void virtblk_config_changed_work(struct work_struct *work)
|
static void virtblk_config_changed_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
|
|
@ -536,8 +536,8 @@ static const char *const virtblk_cache_types[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
cache_type_store(struct device *dev, struct device_attribute *attr,
|
virtblk_cache_type_store(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct gendisk *disk = dev_to_disk(dev);
|
struct gendisk *disk = dev_to_disk(dev);
|
||||||
struct virtio_blk *vblk = disk->private_data;
|
struct virtio_blk *vblk = disk->private_data;
|
||||||
|
|
@ -555,7 +555,8 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
cache_type_show(struct device *dev, struct device_attribute *attr, char *buf)
|
virtblk_cache_type_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
{
|
{
|
||||||
struct gendisk *disk = dev_to_disk(dev);
|
struct gendisk *disk = dev_to_disk(dev);
|
||||||
struct virtio_blk *vblk = disk->private_data;
|
struct virtio_blk *vblk = disk->private_data;
|
||||||
|
|
@ -565,38 +566,12 @@ cache_type_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]);
|
return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR_RW(cache_type);
|
static const struct device_attribute dev_attr_cache_type_ro =
|
||||||
|
__ATTR(cache_type, S_IRUGO,
|
||||||
static struct attribute *virtblk_attrs[] = {
|
virtblk_cache_type_show, NULL);
|
||||||
&dev_attr_serial.attr,
|
static const struct device_attribute dev_attr_cache_type_rw =
|
||||||
&dev_attr_cache_type.attr,
|
__ATTR(cache_type, S_IRUGO|S_IWUSR,
|
||||||
NULL,
|
virtblk_cache_type_show, virtblk_cache_type_store);
|
||||||
};
|
|
||||||
|
|
||||||
static umode_t virtblk_attrs_are_visible(struct kobject *kobj,
|
|
||||||
struct attribute *a, int n)
|
|
||||||
{
|
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
|
||||||
struct gendisk *disk = dev_to_disk(dev);
|
|
||||||
struct virtio_blk *vblk = disk->private_data;
|
|
||||||
struct virtio_device *vdev = vblk->vdev;
|
|
||||||
|
|
||||||
if (a == &dev_attr_cache_type.attr &&
|
|
||||||
!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE))
|
|
||||||
return S_IRUGO;
|
|
||||||
|
|
||||||
return a->mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct attribute_group virtblk_attr_group = {
|
|
||||||
.attrs = virtblk_attrs,
|
|
||||||
.is_visible = virtblk_attrs_are_visible,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct attribute_group *virtblk_attr_groups[] = {
|
|
||||||
&virtblk_attr_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq,
|
static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq,
|
||||||
unsigned int hctx_idx, unsigned int numa_node)
|
unsigned int hctx_idx, unsigned int numa_node)
|
||||||
|
|
@ -719,7 +694,7 @@ static int virtblk_probe(struct virtio_device *vdev)
|
||||||
vblk->tag_set.ops = &virtio_mq_ops;
|
vblk->tag_set.ops = &virtio_mq_ops;
|
||||||
vblk->tag_set.queue_depth = virtblk_queue_depth;
|
vblk->tag_set.queue_depth = virtblk_queue_depth;
|
||||||
vblk->tag_set.numa_node = NUMA_NO_NODE;
|
vblk->tag_set.numa_node = NUMA_NO_NODE;
|
||||||
vblk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_NO_TIMEOUT;
|
vblk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
|
||||||
vblk->tag_set.cmd_size =
|
vblk->tag_set.cmd_size =
|
||||||
sizeof(struct virtblk_req) +
|
sizeof(struct virtblk_req) +
|
||||||
sizeof(struct scatterlist) * sg_elems;
|
sizeof(struct scatterlist) * sg_elems;
|
||||||
|
|
@ -818,9 +793,24 @@ static int virtblk_probe(struct virtio_device *vdev)
|
||||||
|
|
||||||
virtio_device_ready(vdev);
|
virtio_device_ready(vdev);
|
||||||
|
|
||||||
device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
|
device_add_disk(&vdev->dev, vblk->disk);
|
||||||
|
err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
|
||||||
|
if (err)
|
||||||
|
goto out_del_disk;
|
||||||
|
|
||||||
|
if (virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE))
|
||||||
|
err = device_create_file(disk_to_dev(vblk->disk),
|
||||||
|
&dev_attr_cache_type_rw);
|
||||||
|
else
|
||||||
|
err = device_create_file(disk_to_dev(vblk->disk),
|
||||||
|
&dev_attr_cache_type_ro);
|
||||||
|
if (err)
|
||||||
|
goto out_del_disk;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_del_disk:
|
||||||
|
del_gendisk(vblk->disk);
|
||||||
|
blk_cleanup_queue(vblk->disk->queue);
|
||||||
out_free_tags:
|
out_free_tags:
|
||||||
blk_mq_free_tag_set(&vblk->tag_set);
|
blk_mq_free_tag_set(&vblk->tag_set);
|
||||||
out_put_disk:
|
out_put_disk:
|
||||||
|
|
|
||||||
|
|
@ -2399,7 +2399,7 @@ static void blkfront_connect(struct blkfront_info *info)
|
||||||
for (i = 0; i < info->nr_rings; i++)
|
for (i = 0; i < info->nr_rings; i++)
|
||||||
kick_pending_request_queues(&info->rinfo[i]);
|
kick_pending_request_queues(&info->rinfo[i]);
|
||||||
|
|
||||||
device_add_disk(&info->xbdev->dev, info->gd, NULL);
|
device_add_disk(&info->xbdev->dev, info->gd);
|
||||||
|
|
||||||
info->is_ready = 1;
|
info->is_ready = 1;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1576,7 +1576,7 @@ static int zram_add(void)
|
||||||
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
|
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
|
||||||
|
|
||||||
disk_to_dev(zram->disk)->groups = zram_disk_attr_groups;
|
disk_to_dev(zram->disk)->groups = zram_disk_attr_groups;
|
||||||
device_add_disk(NULL, zram->disk, zram_disk_attr_groups);
|
add_disk(zram->disk);
|
||||||
|
|
||||||
strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor));
|
strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1802,7 +1802,7 @@ static int ide_cd_probe(ide_drive_t *drive)
|
||||||
ide_cd_read_toc(drive, &sense);
|
ide_cd_read_toc(drive, &sense);
|
||||||
g->fops = &idecd_ops;
|
g->fops = &idecd_ops;
|
||||||
g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
|
g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
|
||||||
device_add_disk(&drive->gendev, g, NULL);
|
device_add_disk(&drive->gendev, g);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_disk:
|
out_free_disk:
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,7 @@ static int ide_gd_probe(ide_drive_t *drive)
|
||||||
if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
|
if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
|
||||||
g->flags = GENHD_FL_REMOVABLE;
|
g->flags = GENHD_FL_REMOVABLE;
|
||||||
g->fops = &ide_gd_ops;
|
g->fops = &ide_gd_ops;
|
||||||
device_add_disk(&drive->gendev, g, NULL);
|
device_add_disk(&drive->gendev, g);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_disk:
|
out_free_disk:
|
||||||
|
|
|
||||||
|
|
@ -281,9 +281,9 @@ static void clear_translation_pre_enabled(struct amd_iommu *iommu)
|
||||||
|
|
||||||
static void init_translation_status(struct amd_iommu *iommu)
|
static void init_translation_status(struct amd_iommu *iommu)
|
||||||
{
|
{
|
||||||
u64 ctrl;
|
u32 ctrl;
|
||||||
|
|
||||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
if (ctrl & (1<<CONTROL_IOMMU_EN))
|
if (ctrl & (1<<CONTROL_IOMMU_EN))
|
||||||
iommu->flags |= AMD_IOMMU_FLAG_TRANS_PRE_ENABLED;
|
iommu->flags |= AMD_IOMMU_FLAG_TRANS_PRE_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
@ -387,30 +387,30 @@ static void iommu_set_device_table(struct amd_iommu *iommu)
|
||||||
/* Generic functions to enable/disable certain features of the IOMMU. */
|
/* Generic functions to enable/disable certain features of the IOMMU. */
|
||||||
static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
|
static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
|
||||||
{
|
{
|
||||||
u64 ctrl;
|
u32 ctrl;
|
||||||
|
|
||||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
ctrl |= (1ULL << bit);
|
ctrl |= (1 << bit);
|
||||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
|
static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
|
||||||
{
|
{
|
||||||
u64 ctrl;
|
u32 ctrl;
|
||||||
|
|
||||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
ctrl &= ~(1ULL << bit);
|
ctrl &= ~(1 << bit);
|
||||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iommu_set_inv_tlb_timeout(struct amd_iommu *iommu, int timeout)
|
static void iommu_set_inv_tlb_timeout(struct amd_iommu *iommu, int timeout)
|
||||||
{
|
{
|
||||||
u64 ctrl;
|
u32 ctrl;
|
||||||
|
|
||||||
ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
ctrl &= ~CTRL_INV_TO_MASK;
|
ctrl &= ~CTRL_INV_TO_MASK;
|
||||||
ctrl |= (timeout << CONTROL_INV_TIMEOUT) & CTRL_INV_TO_MASK;
|
ctrl |= (timeout << CONTROL_INV_TIMEOUT) & CTRL_INV_TO_MASK;
|
||||||
writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to enable the hardware */
|
/* Function to enable the hardware */
|
||||||
|
|
|
||||||
|
|
@ -2151,7 +2151,7 @@ static int msb_init_disk(struct memstick_dev *card)
|
||||||
set_disk_ro(msb->disk, 1);
|
set_disk_ro(msb->disk, 1);
|
||||||
|
|
||||||
msb_start(card);
|
msb_start(card);
|
||||||
device_add_disk(&card->dev, msb->disk, NULL);
|
device_add_disk(&card->dev, msb->disk);
|
||||||
dbg("Disk added");
|
dbg("Disk added");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1242,7 +1242,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
|
||||||
set_capacity(msb->disk, capacity);
|
set_capacity(msb->disk, capacity);
|
||||||
dev_dbg(&card->dev, "capacity set %ld\n", capacity);
|
dev_dbg(&card->dev, "capacity set %ld\n", capacity);
|
||||||
|
|
||||||
device_add_disk(&card->dev, msb->disk, NULL);
|
device_add_disk(&card->dev, msb->disk);
|
||||||
msb->active = 1;
|
msb->active = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2308,7 +2308,7 @@ static int mmc_add_disk(struct mmc_blk_data *md)
|
||||||
int ret;
|
int ret;
|
||||||
struct mmc_card *card = md->queue.card;
|
struct mmc_card *card = md->queue.card;
|
||||||
|
|
||||||
device_add_disk(md->parent, md->disk, NULL);
|
device_add_disk(md->parent, md->disk);
|
||||||
md->force_ro.show = force_ro_show;
|
md->force_ro.show = force_ro_show;
|
||||||
md->force_ro.store = force_ro_store;
|
md->force_ro.store = force_ro_store;
|
||||||
sysfs_attr_init(&md->force_ro.attr);
|
sysfs_attr_init(&md->force_ro.attr);
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
|
||||||
if (new->readonly)
|
if (new->readonly)
|
||||||
set_disk_ro(gd, 1);
|
set_disk_ro(gd, 1);
|
||||||
|
|
||||||
device_add_disk(&new->mtd->dev, gd, NULL);
|
device_add_disk(&new->mtd->dev, gd);
|
||||||
|
|
||||||
if (new->disk_attributes) {
|
if (new->disk_attributes) {
|
||||||
ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
|
ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,49 +1,13 @@
|
||||||
#!/usr/bin/make
|
#!/usr/bin/make
|
||||||
# Makefile for building Linux Broadcom Gigabit ethernet driver as a module.
|
# Makefile for building Linux Broadcom Gigabit ethernet driver as a module.
|
||||||
# $id$
|
# $id$
|
||||||
KVER=
|
|
||||||
ifeq ($(KVER),)
|
|
||||||
KVER=$(shell uname -r)
|
|
||||||
endif
|
|
||||||
|
|
||||||
KVER_MAJ=$(shell echo $(KVER) | cut -d "." -f1)
|
KERNELDIR=$(shell pwd)
|
||||||
|
|
||||||
__ARCH=$(shell uname -m)
|
ifneq ($(shell ls /$(KERNELDIR)/source > /dev/null 2>&1 && echo source),)
|
||||||
|
LINUXSRC=/$(KERNELDIR)/source
|
||||||
# PREFIX may be set by the RPM build to set the effective root.
|
|
||||||
PREFIX=
|
|
||||||
ifeq ($(shell ls /lib/modules/$(KVER)/build > /dev/null 2>&1 && echo build),)
|
|
||||||
# SuSE source RPMs
|
|
||||||
_KVER=$(shell echo $(KVER) | cut -d "-" -f1,2)
|
|
||||||
_KFLA=$(shell echo $(KVER) | cut -d "-" -f3)
|
|
||||||
_ARCH=$(shell file -b /lib/modules/$(shell uname -r)/build | cut -d "/" -f5)
|
|
||||||
ifeq ($(_ARCH),)
|
|
||||||
_ARCH=$(__ARCH)
|
|
||||||
endif
|
|
||||||
ifeq ($(shell ls /usr/src/linux-$(_KVER)-obj > /dev/null 2>&1 && echo linux),)
|
|
||||||
ifeq ($(shell ls /usr/src/kernels/$(KVER)-$(__ARCH) > /dev/null 2>&1 && echo linux),)
|
|
||||||
LINUX=
|
|
||||||
else
|
|
||||||
LINUX=/usr/src/kernels/$(KVER)-$(__ARCH)
|
|
||||||
LINUXSRC=$(LINUX)
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
LINUX=/usr/src/linux-$(_KVER)-obj/$(_ARCH)/$(_KFLA)
|
|
||||||
LINUXSRC=/usr/src/linux-$(_KVER)
|
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
LINUX=/lib/modules/$(KVER)/build
|
LINUXSRC=$(KERNELDIR)
|
||||||
ifeq ($(shell ls /lib/modules/$(KVER)/source > /dev/null 2>&1 && echo source),)
|
|
||||||
LINUXSRC=$(LINUX)
|
|
||||||
else
|
|
||||||
LINUXSRC=/lib/modules/$(KVER)/source
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
KDIR ?= $(srctree)
|
|
||||||
ifneq ($(KDIR),)
|
|
||||||
LINUX=$(KDIR)
|
|
||||||
LINUXSRC=$(LINUX)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(shell ls $(LINUXSRC)/include/uapi/linux > /dev/null 2>&1 && echo uapi),)
|
ifeq ($(shell ls $(LINUXSRC)/include/uapi/linux > /dev/null 2>&1 && echo uapi),)
|
||||||
|
|
@ -52,26 +16,6 @@ else
|
||||||
UAPI=uapi
|
UAPI=uapi
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(BCMMODDIR),)
|
|
||||||
ifeq ($(shell ls /lib/modules/$(KVER)/updates > /dev/null 2>&1 && echo 1),1)
|
|
||||||
BCMMODDIR=/lib/modules/$(KVER)/updates
|
|
||||||
else
|
|
||||||
ifeq ($(shell grep -q "search.*[[:space:]]updates" /etc/depmod.conf > /dev/null 2>&1 && echo 1),1)
|
|
||||||
BCMMODDIR=/lib/modules/$(KVER)/updates
|
|
||||||
else
|
|
||||||
ifeq ($(shell grep -q "search.*[[:space:]]updates" /etc/depmod.d/* > /dev/null 2>&1 && echo 1),1)
|
|
||||||
BCMMODDIR=/lib/modules/$(KVER)/updates
|
|
||||||
else
|
|
||||||
ifeq ($(shell expr $(KVER_MAJ) \>= 3), 1)
|
|
||||||
BCMMODDIR=/lib/modules/$(KVER)/updates
|
|
||||||
else
|
|
||||||
BCMMODDIR=/lib/modules/$(KVER)/kernel/drivers/net
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -o "pci_enable_msix_range" $(LINUXSRC)/include/linux/pci.h),)
|
ifneq ($(shell grep -o "pci_enable_msix_range" $(LINUXSRC)/include/linux/pci.h),)
|
||||||
DISTRO_CFLAG = -DHAVE_MSIX_RANGE
|
DISTRO_CFLAG = -DHAVE_MSIX_RANGE
|
||||||
else
|
else
|
||||||
|
|
@ -84,6 +28,10 @@ ifneq ($(shell grep -o "msix_cap" $(LINUXSRC)/include/linux/pci.h),)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(shell grep -o "module_pci_driver" $(LINUXSRC)/include/linux/pci.h),)
|
||||||
|
DISTRO_CFLAG += -DHAVE_MODULE_PCI_DRIVER
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "GENL_ID_GENERATE" $(LINUXSRC)/include/uapi/linux/genetlink.h),)
|
ifneq ($(shell grep -so "GENL_ID_GENERATE" $(LINUXSRC)/include/uapi/linux/genetlink.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_GENL_ID_GENERATE
|
DISTRO_CFLAG += -DHAVE_GENL_ID_GENERATE
|
||||||
endif
|
endif
|
||||||
|
|
@ -175,38 +123,6 @@ ifneq ($(shell grep -o "dma_set_coherent_mask" $(LINUXSRC)/include/linux/dma-map
|
||||||
DISTRO_CFLAG += -DHAVE_SET_COHERENT_MASK
|
DISTRO_CFLAG += -DHAVE_SET_COHERENT_MASK
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep "dma_buf_export" $(LINUXSRC)/include/linux/dma-buf.h | grep "exp_info"),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMA_EXPORT
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "dma_buf_export" $(LINUXSRC)/include/linux/dma-buf.h | grep "define"),)
|
|
||||||
ifneq ($(shell grep "dma_buf_export" $(LINUXSRC)/include/linux/dma-buf.h | grep "resv"),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMA_EXPORT_FLAG_RESV
|
|
||||||
else
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMA_EXPORT_FLAG
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "(*kmap_atomic)" $(LINUXSRC)/include/linux/dma-buf.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMABUF_KMAP_ATOMIC
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "(*kmap)" $(LINUXSRC)/include/linux/dma-buf.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMABUF_KMAP
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "(*map_atomic)" $(LINUXSRC)/include/linux/dma-buf.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMABUF_MAP_ATOMIC
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "(*map)" $(LINUXSRC)/include/linux/dma-buf.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMABUF_MAP
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -w "attach" $(LINUXSRC)/include/linux/dma-buf.h | grep "struct device"),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DMABUF_ATTACH_DEV
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell ls $(LINUXSRC)/include/linux/dma-attrs.h > /dev/null 2>&1 && echo dma_attrs),)
|
ifneq ($(shell ls $(LINUXSRC)/include/linux/dma-attrs.h > /dev/null 2>&1 && echo dma_attrs),)
|
||||||
DISTRO_CFLAG += -DHAVE_DMA_ATTRS_H
|
DISTRO_CFLAG += -DHAVE_DMA_ATTRS_H
|
||||||
endif
|
endif
|
||||||
|
|
@ -223,18 +139,15 @@ ifneq ($(shell grep -o "dma_zalloc_coherent" $(LINUXSRC)/include/linux/dma-mappi
|
||||||
DISTRO_CFLAG += -DHAVE_DMA_ZALLOC_COHERENT
|
DISTRO_CFLAG += -DHAVE_DMA_ZALLOC_COHERENT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(shell grep -o "ndo_add_vxlan_port" $(LINUXSRC)/include/linux/netdevice.h),)
|
||||||
|
DISTRO_CFLAG += -DHAVE_NDO_ADD_VXLAN
|
||||||
|
ifneq ($(shell grep -so "vxlan_get_rx_port" $(LINUXSRC)/include/net/vxlan.h),)
|
||||||
|
DISTRO_CFLAG += -DHAVE_VXLAN_GET_RX_PORT
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -o "ndo_udp_tunnel_add" $(LINUXSRC)/include/linux/netdevice.h),)
|
ifneq ($(shell grep -o "ndo_udp_tunnel_add" $(LINUXSRC)/include/linux/netdevice.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_NDO_UDP_TUNNEL
|
DISTRO_CFLAG += -DHAVE_NDO_UDP_TUNNEL
|
||||||
ifneq ($(shell grep -A 24 "net_device_ops_extended" $(LINUXSRC)/include/linux/netdevice.h | grep -o "ndo_udp_tunnel_add"),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_NDO_UDP_TUNNEL_RH
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
ifneq ($(shell grep -o "ndo_add_vxlan_port" $(LINUXSRC)/include/linux/netdevice.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_NDO_ADD_VXLAN
|
|
||||||
ifneq ($(shell grep -so "vxlan_get_rx_port" $(LINUXSRC)/include/net/vxlan.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_VXLAN_GET_RX_PORT
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -o "struct dev_addr_list" $(LINUXSRC)/include/linux/netdevice.h),)
|
ifneq ($(shell grep -o "struct dev_addr_list" $(LINUXSRC)/include/linux/netdevice.h),)
|
||||||
|
|
@ -284,9 +197,6 @@ ifneq ($(shell ls $(LINUXSRC)/include/net/flow_offload.h > /dev/null 2>&1 && ech
|
||||||
ifneq ($(shell grep -o "FLOW_ACTION_POLICE" $(LINUXSRC)/include/net/flow_offload.h),)
|
ifneq ($(shell grep -o "FLOW_ACTION_POLICE" $(LINUXSRC)/include/net/flow_offload.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_FLOW_ACTION_POLICE
|
DISTRO_CFLAG += -DHAVE_FLOW_ACTION_POLICE
|
||||||
endif
|
endif
|
||||||
ifneq ($(shell grep -o "flow_action_basic_hw_stats_check" $(LINUXSRC)/include/net/flow_offload.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_FLOW_ACTION_BASIC_HW_STATS_CHECK
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell ls $(LINUXSRC)/include/net/udp_tunnel.h > /dev/null 2>&1 && echo udp_tunnel),)
|
ifneq ($(shell ls $(LINUXSRC)/include/net/udp_tunnel.h > /dev/null 2>&1 && echo udp_tunnel),)
|
||||||
|
|
@ -348,10 +258,6 @@ ifneq ($(shell grep -so "ETHTOOL_LINK_MODE_25000baseCR_Full_BIT" $(LINUXSRC)/inc
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "ETHTOOL_LINK_MODE_50000baseCR_Full_BIT" $(LINUXSRC)/include/$(UAPI)/linux/ethtool.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_ETHTOOL_GLINKSETTINGS_PAM4
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -so "ethtool_tcpip6_spec" $(LINUXSRC)/include/$(UAPI)/linux/ethtool.h),)
|
ifneq ($(shell grep -so "ethtool_tcpip6_spec" $(LINUXSRC)/include/$(UAPI)/linux/ethtool.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_ETHTOOL_IP6_SPEC
|
DISTRO_CFLAG += -DHAVE_ETHTOOL_IP6_SPEC
|
||||||
endif
|
endif
|
||||||
|
|
@ -474,8 +380,11 @@ ifneq ($(shell grep -o "ndo_set_vf_vlan_rh73" $(LINUXSRC)/include/linux/netdevic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -o "ndo_set_vf_trust" $(LINUXSRC)/include/linux/netdevice.h),)
|
ifneq ($(shell grep -o "ndo_set_vf_trust" $(LINUXSRC)/include/linux/netdevice.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_NDO_SET_VF_TRUST
|
ifeq ($(shell grep -o "net_device_ops_ext" $(LINUXSRC)/include/linux/netdevice.h),)
|
||||||
|
DISTRO_CFLAG += -DHAVE_NDO_SET_VF_TRUST
|
||||||
|
endif
|
||||||
ifneq ($(shell grep -A 3 "net_device_ops_extended" $(LINUXSRC)/include/linux/netdevice.h | grep -o "ndo_set_vf_trust"),)
|
ifneq ($(shell grep -A 3 "net_device_ops_extended" $(LINUXSRC)/include/linux/netdevice.h | grep -o "ndo_set_vf_trust"),)
|
||||||
|
DISTRO_CFLAG += -DHAVE_NDO_SET_VF_TRUST
|
||||||
DISTRO_CFLAG += -DHAVE_NDO_SET_VF_TRUST_RH
|
DISTRO_CFLAG += -DHAVE_NDO_SET_VF_TRUST_RH
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
@ -644,10 +553,6 @@ ifneq ($(shell grep -so "struct xdp_rxq_info" $(LINUXSRC)/include/net/xdp.h),)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "xdp_data_hard_end" $(LINUXSRC)/include/net/xdp.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_XDP_FRAME_SZ
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -so "page_pool_release_page" $(LINUXSRC)/include/net/page_pool.h),)
|
ifneq ($(shell grep -so "page_pool_release_page" $(LINUXSRC)/include/net/page_pool.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_PAGE_POOL_RELEASE_PAGE
|
DISTRO_CFLAG += -DHAVE_PAGE_POOL_RELEASE_PAGE
|
||||||
endif
|
endif
|
||||||
|
|
@ -744,14 +649,6 @@ ifneq ($(shell grep -o "pci_physfn" $(LINUXSRC)/include/linux/pci.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_PCI_PHYSFN
|
DISTRO_CFLAG += -DHAVE_PCI_PHYSFN
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -o "pcie_flr" $(LINUXSRC)/include/linux/pci.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_PCIE_FLR
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -o "pci_get_dsn" $(LINUXSRC)/include/linux/pci.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_PCI_GET_DSN
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell ls $(LINUXSRC)/include/$(UAPI)/linux/net_tstamp.h > /dev/null 2>&1 && echo net_tstamp),)
|
ifneq ($(shell ls $(LINUXSRC)/include/$(UAPI)/linux/net_tstamp.h > /dev/null 2>&1 && echo net_tstamp),)
|
||||||
ifneq ($(shell ls $(LINUXSRC)/include/linux/timecounter.h > /dev/null 2>&1 && echo timecounter),)
|
ifneq ($(shell ls $(LINUXSRC)/include/linux/timecounter.h > /dev/null 2>&1 && echo timecounter),)
|
||||||
ifneq ($(shell ls $(LINUXSRC)/include/linux/timekeeping.h > /dev/null 2>&1 && echo timekeeping),)
|
ifneq ($(shell ls $(LINUXSRC)/include/linux/timekeeping.h > /dev/null 2>&1 && echo timekeeping),)
|
||||||
|
|
@ -762,10 +659,6 @@ ifneq ($(shell ls $(LINUXSRC)/include/$(UAPI)/linux/net_tstamp.h > /dev/null 2>&
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "gettimex64" $(LINUXSRC)/include/linux/ptp_clock_kernel.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_PTP_GETTIMEX64
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -o "time64_to_tm" $(LINUXSRC)/include/linux/time.h),)
|
ifneq ($(shell grep -o "time64_to_tm" $(LINUXSRC)/include/linux/time.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_TIME64
|
DISTRO_CFLAG += -DHAVE_TIME64
|
||||||
endif
|
endif
|
||||||
|
|
@ -811,9 +704,6 @@ endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "info_get" $(LINUXSRC)/include/net/devlink.h),)
|
ifneq ($(shell grep -so "info_get" $(LINUXSRC)/include/net/devlink.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_DEVLINK_INFO
|
DISTRO_CFLAG += -DHAVE_DEVLINK_INFO
|
||||||
ifneq ($(shell grep -so "devlink_info_board_serial_number_put" $(LINUXSRC)/include/net/devlink.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DEVLINK_INFO_BSN_PUT
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "flash_update" $(LINUXSRC)/include/net/devlink.h),)
|
ifneq ($(shell grep -so "flash_update" $(LINUXSRC)/include/net/devlink.h),)
|
||||||
|
|
@ -840,10 +730,6 @@ ifneq ($(shell grep -so "devlink_health_reporter_recovery_done" $(LINUXSRC)/incl
|
||||||
DISTRO_CFLAG += -DHAVE_DEVLINK_HEALTH_REPORTER_RECOVERY_DONE
|
DISTRO_CFLAG += -DHAVE_DEVLINK_HEALTH_REPORTER_RECOVERY_DONE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -s -A 2 "devlink_health_reporter_create" $(LINUXSRC)/include/net/devlink.h | grep auto_recover),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DEVLINK_HEALTH_AUTO_RECOVER
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Check if the file exists or not
|
# Check if the file exists or not
|
||||||
ifneq ($(shell grep -s "switchdev_ops" $(LINUXSRC)/include/net/switchdev.h),)
|
ifneq ($(shell grep -s "switchdev_ops" $(LINUXSRC)/include/net/switchdev.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_SWITCHDEV
|
DISTRO_CFLAG += -DHAVE_SWITCHDEV
|
||||||
|
|
@ -857,10 +743,6 @@ ifneq ($(shell grep -so "(*ieee_delapp)" $(LINUXSRC)/include/net/dcbnl.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_IEEE_DELAPP
|
DISTRO_CFLAG += -DHAVE_IEEE_DELAPP
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -so "dcb_ieee_getapp_prio_dscp_mask_map" $(LINUXSRC)/include/net/dcbnl.h),)
|
|
||||||
DISTRO_CFLAG += -DHAVE_DSCP_MASK_MAP
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(shell grep -o cpumask_local_spread $(LINUXSRC)/include/linux/cpumask.h),)
|
ifneq ($(shell grep -o cpumask_local_spread $(LINUXSRC)/include/linux/cpumask.h),)
|
||||||
DISTRO_CFLAG += -DHAVE_CPUMASK_LOCAL_SPREAD
|
DISTRO_CFLAG += -DHAVE_CPUMASK_LOCAL_SPREAD
|
||||||
endif
|
endif
|
||||||
|
|
@ -885,59 +767,11 @@ ifneq ($(shell grep -o hwmon_device_register_with_groups $(LINUXSRC)/include/lin
|
||||||
DISTRO_CFLAG += -DHAVE_NEW_HWMON_API
|
DISTRO_CFLAG += -DHAVE_NEW_HWMON_API
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(shell grep -o ETH_RESET_CRASHDUMP $(LINUXSRC)/include/uapi/linux/ethtool.h),)
|
EXTRA_CFLAGS += ${DISTRO_CFLAG} -g -DCHIMP_FW -D__LINUX -DCONFIG_BNXT_SRIOV -DCONFIG_BNXT_DCB -DCONFIG_BNXT_FLASHDEV -DHSI_DBG_DISABLE -DCONFIG_BNXT_LFC
|
||||||
DISTRO_CFLAG += -DHAVE_ETHTOOL_RESET_CRASHDUMP
|
|
||||||
endif
|
|
||||||
|
|
||||||
override EXTRA_CFLAGS += ${DISTRO_CFLAG} -g -DCHIMP_FW -D__LINUX -DCONFIG_BNXT_SRIOV -DCONFIG_BNXT_DCB -DCONFIG_BNXT_FLASHDEV -DHSI_DBG_DISABLE -DCONFIG_BNXT_LFC
|
|
||||||
|
|
||||||
cflags-y += $(EXTRA_CFLAGS)
|
cflags-y += $(EXTRA_CFLAGS)
|
||||||
|
|
||||||
BCM_DRV = bnxt_en.ko
|
BNXT_DBGFS_OBJ = bnxt_debugfs_cpt.o
|
||||||
ifneq ($(KERNELRELEASE),)
|
|
||||||
|
|
||||||
ifeq ($(shell expr $(KVER_MAJ) \>= 5), 1)
|
obj-$(CONFIG_BNXT) += bnxt_en.o
|
||||||
BNXT_DBGFS_OBJ = bnxt_debugfs.o
|
bnxt_en-y := bnxt.o bnxt_ethtool.o bnxt_sriov.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_tc.o bnxt_devlink.o bnxt_lfc.o bnxt_netlink.o bnxt_dim.o $(BNXT_DBGFS_OBJ) #decode_hsi.o
|
||||||
else
|
|
||||||
BNXT_DBGFS_OBJ = bnxt_debugfs_cpt.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-m += bnxt_en.o
|
|
||||||
bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_ethtool.o bnxt_sriov.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_tc.o bnxt_devlink.o bnxt_lfc.o bnxt_netlink.o bnxt_dim.o bnxt_eem.o $(BNXT_DBGFS_OBJ) #decode_hsi.o
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
default:
|
|
||||||
ifeq ($(CROSS_COMPILE),)
|
|
||||||
make -C $(LINUX) M=$(shell pwd) modules
|
|
||||||
else ifneq ($(CROSS_COMPILE),)
|
|
||||||
make -C $(LINUXSRC) M=$(shell pwd) modules CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH)
|
|
||||||
endif
|
|
||||||
|
|
||||||
yocto_all:
|
|
||||||
$(MAKE) -C $(LINUXSRC) M=$(shell pwd)
|
|
||||||
|
|
||||||
modules_install:
|
|
||||||
$(MAKE) -C $(LINUXSRC) M=$(shell pwd) modules_install
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
install: default
|
|
||||||
@if [ "$(KDIR)" != "" ]; then \
|
|
||||||
echo "Cannot use install with KDIR option"; exit 2;\
|
|
||||||
fi
|
|
||||||
mkdir -p $(PREFIX)$(BCMMODDIR);
|
|
||||||
install -m 444 $(BCM_DRV) $(PREFIX)$(BCMMODDIR);
|
|
||||||
@if [ "$(PREFIX)" = "" ]; then /sbin/depmod -a ;\
|
|
||||||
else echo " *** Run '/sbin/depmod -a' to update the module database.";\
|
|
||||||
fi
|
|
||||||
|
|
||||||
.PHONEY: all clean install
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -f bnxt.o bnxt.mod.c bnxt.mod.o .bnxt.*.cmd *.cmd *.markers *.order *.symvers decode_hsi.o .decode_*
|
|
||||||
-rm -rf .tmp_versions
|
|
||||||
-rm -rf bnxt_en.o bnxt_en.ko bnxt_en.mod.o bnxt_en.mod.c .bnxt_en.* bnxt_sriov.o .bnxt_sriov.* bnxt_ethtool.o .bnxt_ethtool.* bnxt_dcb.o .bnxt_dcb.* bnxt_ulp.o .bnxt_ulp.* bnxt_ptp.o .bnxt_ptp.* bnxt_xdp.o .bnxt_xdp.* bnxt_lfc.o .bnxt_lfc.* bnxt_hwrm.o .bnxt_hwrm.*
|
|
||||||
-rm -rf bnxt_vfr.o .bnxt_vfr.* bnxt_tc.o .bnxt_tc.* bnxt_devlink.o .bnxt_devlink.* bnxt_netlink.o .bnxt_netlink.*
|
|
||||||
-rm -rf bnxt_dim.o .bnxt_dim.* bnxt_debugfs*.o .bnxt_debugfs* bnxt_eem.o .bnxt_eem*
|
|
||||||
-rm -f Module.markers Module.symvers modules.order
|
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,8 @@ module option, the vxlan.ko module must be loaded before the bnxt_en.ko module.
|
||||||
Using newer kernels, the hwmon.ko module may need to be loaded first if
|
Using newer kernels, the hwmon.ko module may need to be loaded first if
|
||||||
CONFIG_HWMON_MODULE kernel option is set as a module option.
|
CONFIG_HWMON_MODULE kernel option is set as a module option.
|
||||||
|
|
||||||
Using kernel versions 4.6 or higher, devlink.ko module may need to be loaded
|
Using newer kernels, devlink.ko module may need to be loaded first if
|
||||||
first if CONFIG_NET_DEVLINK kernel option is set as a module option.
|
CONFIG_NET_DEVLINK kernel option is set as a module option.
|
||||||
|
|
||||||
BNXT_EN Driver Settings
|
BNXT_EN Driver Settings
|
||||||
=======================
|
=======================
|
||||||
|
|
@ -266,67 +266,35 @@ for rx and tx but must both be non-zero.
|
||||||
|
|
||||||
ethtool -x eth0
|
ethtool -x eth0
|
||||||
|
|
||||||
Note that the RSS indirection table size may vary depending on the device
|
|
||||||
and the number of RX channels.
|
|
||||||
|
|
||||||
13. Set 40-byte RSS hash key:
|
13. Set 40-byte RSS hash key:
|
||||||
|
|
||||||
ethtool -X eth0 hkey 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27
|
ethtool -X eth0 hkey 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27
|
||||||
|
|
||||||
14. Set RSS indirection table:
|
14. Run self test:
|
||||||
|
|
||||||
ethtool -X eth0 [start N] [ equal N | weight W0 W1 ... | default ]
|
|
||||||
|
|
||||||
Example: Set RSS indirection table to have equal distribution for the first
|
|
||||||
four channels:
|
|
||||||
|
|
||||||
ethtool -X eth0 equal 4
|
|
||||||
|
|
||||||
Example: Set RSS indirection table to have equal distribution for six
|
|
||||||
channels starting from channel 2:
|
|
||||||
|
|
||||||
ethtool -X eth0 start 2 equal 6
|
|
||||||
|
|
||||||
Note that the start parameter is 0-based.
|
|
||||||
|
|
||||||
Example: Set RSS indirection table to have weight distributions of 1:2:3:4
|
|
||||||
for four channels starting from channel 4:
|
|
||||||
|
|
||||||
ethtool -X eth0 start 4 weight 1 2 3 4
|
|
||||||
|
|
||||||
Note that the number of channels being configured must be valid and must not
|
|
||||||
exceed the number of RX or combined channels. The configured settings will be
|
|
||||||
preserved whenever possible even when the number of RX or combined channels is
|
|
||||||
changed. In some cases when the settings cannot be preserved, the indirection
|
|
||||||
table will revert back to default even distribution for all channels.
|
|
||||||
|
|
||||||
15. Run self test:
|
|
||||||
|
|
||||||
ethtool -t eth0
|
ethtool -t eth0
|
||||||
|
|
||||||
Note that only single function PFs can execute self tests. If a PF has
|
Note that only single function PFs can execute self tests. If a PF has
|
||||||
active VFs, only online tests can be executed.
|
active VFs, only online tests can be executed.
|
||||||
|
|
||||||
16. Collect Firmware Coredump:
|
15. Collect Firmware Coredump:
|
||||||
|
|
||||||
ethtool -w eth0 data FILENAME
|
ethtool -w eth0 data FILENAME
|
||||||
|
|
||||||
17. Set coredump flags:
|
16. Set coredump flags:
|
||||||
|
|
||||||
ethtool -W eth0 N
|
ethtool -W eth0 N
|
||||||
|
|
||||||
Note that N is '0' for collecting live dump and '1' for collecting saved
|
Note that N is '0' for collecting live dump and '1' for collecting saved
|
||||||
crash dump. 'crash dump' is supported only on adapters that support
|
crash dump.
|
||||||
TEE_BNXT_FW option.
|
|
||||||
|
|
||||||
18. Reset the device:
|
17. Reset the device:
|
||||||
|
|
||||||
ethtool --reset eth0 [flags N] [type]
|
ethtool --reset eth0 [flags N] [type]
|
||||||
|
|
||||||
Note that driver supports 'ap' and 'all' type of resets. Also, '--reset'
|
Note that driver supports 'ap' and 'all' type of resets.
|
||||||
option is available from ethtool version 4.15 or newer.
|
|
||||||
|
|
||||||
19. Add receive network flow classification filters.
|
18. Add receive network flow classification filters.
|
||||||
|
|
||||||
ethtool -N eth0 flow-type ether|tcp4|udp4|tcp6|udp6 FLOW_SPEC
|
ethtool -N eth0 flow-type ether|tcp4|udp4|tcp6|udp6 FLOW_SPEC
|
||||||
|
|
||||||
|
|
@ -348,9 +316,6 @@ Example: UDP/IPv4 4-tuple filter to rx queue 2
|
||||||
ethtool -N eth0 flow-type udp4 dst-ip 192.168.0.1 src-ip 192.168.0.2 \
|
ethtool -N eth0 flow-type udp4 dst-ip 192.168.0.1 src-ip 192.168.0.2 \
|
||||||
dst-port 2049 action 2
|
dst-port 2049 action 2
|
||||||
|
|
||||||
The action parameter must be greater than or equal to 0 to specify the
|
|
||||||
RX queue/ring number. Negative action parameters are not supported.
|
|
||||||
|
|
||||||
The flow-type is counted as the first tuple and must always be specified.
|
The flow-type is counted as the first tuple and must always be specified.
|
||||||
At least one additional tuple must be specified for TCP/UDP filters. A
|
At least one additional tuple must be specified for TCP/UDP filters. A
|
||||||
tuple must either be completely specified or not specified at all. A
|
tuple must either be completely specified or not specified at all. A
|
||||||
|
|
@ -364,10 +329,7 @@ another 4-tuple filter, for example. In general, the more specific
|
||||||
|
|
||||||
If the filter is created succesfully, the ID of the filter will be returned
|
If the filter is created succesfully, the ID of the filter will be returned
|
||||||
by ethtool. ethtool -n will also display the current list of filters with
|
by ethtool. ethtool -n will also display the current list of filters with
|
||||||
their IDs. A specific filter can be deleted by specifying the ID. The
|
their IDs. A specific filter can be deleted by specifying the ID.
|
||||||
"loc" parameter that allows the user to specify the location of the filter
|
|
||||||
is not supported. It must be the default 0xffffffff which means that the
|
|
||||||
driver will choose the location/ID.
|
|
||||||
|
|
||||||
Example: Delete filter ID 3
|
Example: Delete filter ID 3
|
||||||
|
|
||||||
|
|
@ -378,7 +340,7 @@ filters, any duplicate 5-tuple filters added by ethtool will be rejected.
|
||||||
It is generally not recommended to enable accelerated RFS and create
|
It is generally not recommended to enable accelerated RFS and create
|
||||||
static 5-tuple filters on the same function.
|
static 5-tuple filters on the same function.
|
||||||
|
|
||||||
20. See ethtool man page for more options.
|
19. See ethtool man page for more options.
|
||||||
|
|
||||||
|
|
||||||
Autoneg
|
Autoneg
|
||||||
|
|
@ -1138,19 +1100,6 @@ packets bigger than 1518 bytes when using earlier versions of the firmware.
|
||||||
Newer version of the firmware has reprogrammed the counter to count
|
Newer version of the firmware has reprogrammed the counter to count
|
||||||
packets bigger than 9600 bytes.
|
packets bigger than 9600 bytes.
|
||||||
|
|
||||||
If the "rx_discards" and "rx_buf_errors" counters are high compared to the
|
|
||||||
total recieve packets for that ring, it generally means that the host CPU
|
|
||||||
is not processing the incoming packets fast enough and causing packet drops.
|
|
||||||
The number of receive packets dropped is indicated by these counters.
|
|
||||||
Increasing the receive ring size may reduce the number of dropped packets (See
|
|
||||||
BNXT_EN Driver Settings section above, examples 5 and 6).
|
|
||||||
|
|
||||||
The "rx_l4_csum_errors" counter will increment for every TCP/UDP checksum
|
|
||||||
error detected by hardware on each ring if RX checksum offload is enabled.
|
|
||||||
Such packets will be rejected by the stack and similar stack error
|
|
||||||
counters for TCP/UDP will also increment. Note that IPv4 checksum is
|
|
||||||
always verified by the stack and not offloaded.
|
|
||||||
|
|
||||||
|
|
||||||
Unloading and Removing Driver
|
Unloading and Removing Driver
|
||||||
=============================
|
=============================
|
||||||
|
|
@ -1213,20 +1162,13 @@ below steps
|
||||||
Devlink
|
Devlink
|
||||||
=======
|
=======
|
||||||
|
|
||||||
In kernel versions 4.6 or higher, some operations on bnxt_en driver can be done
|
In newer kernels, some operations on bnxt_en driver can be done using devlink.
|
||||||
using devlink.
|
|
||||||
|
|
||||||
Devlink tool is part of iproute2 routing commands and utilities. Latest devlink
|
Devlink tool is part of iproute2 routing commands and utilities. Latest devlink
|
||||||
can be downloaded from http://www.kernel.org/pub/linux/utils/net/iproute2/,
|
can be downloaded from http://www.kernel.org/pub/linux/utils/net/iproute2/,
|
||||||
if it is not already installed.
|
if it is not already installed. Following are some examples on how to use
|
||||||
|
devlink. See the devlink man page for more information.
|
||||||
|
|
||||||
As devlink tool is evolving, use latest kernel and iproute2 tool available for
|
devlink examples:
|
||||||
all features via devlink.
|
|
||||||
|
|
||||||
Following are some examples on how to use devlink. See the devlink man page
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
Some devlink examples:
|
|
||||||
|
|
||||||
1. Command to display board information and firmware versions:
|
1. Command to display board information and firmware versions:
|
||||||
|
|
||||||
|
|
@ -1242,19 +1184,15 @@ pci/0000:3b:00.0:
|
||||||
serial_number B0-26-28-FF-FE-C8-85-20
|
serial_number B0-26-28-FF-FE-C8-85-20
|
||||||
versions:
|
versions:
|
||||||
fixed:
|
fixed:
|
||||||
board.id BCM957508-P2100G
|
|
||||||
asic.id 1750
|
asic.id 1750
|
||||||
asic.rev 1
|
asic.rev 1
|
||||||
running:
|
running:
|
||||||
fw 216.0.167.0
|
fw 216.0.167.0
|
||||||
fw.psid 0.0.6
|
fw.psid 0.0.6
|
||||||
fw.mgmt 216.0.167.0
|
fw.app 216.0.167.0
|
||||||
fw.mgmt.api 1.10.1
|
fw.mgmt 864.0.32.0
|
||||||
fw.ncsi 864.0.32.0
|
|
||||||
fw.roce 216.0.157.0
|
fw.roce 216.0.157.0
|
||||||
|
|
||||||
Note that 'info' is supported in 5.1 or higher kernel versions.
|
|
||||||
|
|
||||||
2. Updating firmware:
|
2. Updating firmware:
|
||||||
|
|
||||||
devlink dev flash DEV file PATH
|
devlink dev flash DEV file PATH
|
||||||
|
|
@ -1264,8 +1202,6 @@ Example:
|
||||||
|
|
||||||
Note: File path is relative to /lib/firmware directory.
|
Note: File path is relative to /lib/firmware directory.
|
||||||
|
|
||||||
Note that 'flash' is supported in 5.1 or higher kernel versions.
|
|
||||||
|
|
||||||
3. Dump device level driver parameter information:
|
3. Dump device level driver parameter information:
|
||||||
|
|
||||||
devlink dev param show
|
devlink dev param show
|
||||||
|
|
@ -1284,8 +1220,6 @@ pci/0000:3b:00.0:
|
||||||
values:
|
values:
|
||||||
cmode permanent value true
|
cmode permanent value true
|
||||||
|
|
||||||
Note that 'param' is supported in 4.19 or higher kernel versions.
|
|
||||||
|
|
||||||
5. Set the device level driver parameter information:
|
5. Set the device level driver parameter information:
|
||||||
|
|
||||||
devlink dev param set DEV name PARAMETER value VALUE cmode \
|
devlink dev param set DEV name PARAMETER value VALUE cmode \
|
||||||
|
|
@ -1300,13 +1234,13 @@ Example:
|
||||||
devlink health show [ DEV reporter REPORTER ]
|
devlink health show [ DEV reporter REPORTER ]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
devlink health show pci/0000:3b:00.0 reporter fw_fatal
|
devlink health show pci/0000:3b:00.0 reporter fw
|
||||||
|
|
||||||
will show:
|
will show:
|
||||||
|
|
||||||
pci/0000:3b:00.0:
|
pci/0000:3b:00.0:
|
||||||
name fw_fatal
|
name fw
|
||||||
state healthy error 2 recover 2 grace_period 0 auto_recover true
|
state healthy error 0 recover 0
|
||||||
|
|
||||||
Example2:
|
Example2:
|
||||||
devlink health show pci/0000:af:00.0 reporter fw_reset
|
devlink health show pci/0000:af:00.0 reporter fw_reset
|
||||||
|
|
@ -1320,9 +1254,6 @@ pci/0000:af:00.0:
|
||||||
Note that health reporters are created only when corresponding features
|
Note that health reporters are created only when corresponding features
|
||||||
are enabled in NVM configuration.
|
are enabled in NVM configuration.
|
||||||
|
|
||||||
Note that "fw" health reporter information does not support any type of
|
|
||||||
reset, so the counters displayed by show command will be 0's.
|
|
||||||
|
|
||||||
7. Run diagnostics via health reporter:
|
7. Run diagnostics via health reporter:
|
||||||
|
|
||||||
devlink health diagnose DEV reporter REPORTER
|
devlink health diagnose DEV reporter REPORTER
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -132,10 +132,6 @@ struct tx_cmp {
|
||||||
__le32 tx_cmp_flags_type;
|
__le32 tx_cmp_flags_type;
|
||||||
#define CMP_TYPE (0x3f << 0)
|
#define CMP_TYPE (0x3f << 0)
|
||||||
#define CMP_TYPE_TX_L2_CMP 0
|
#define CMP_TYPE_TX_L2_CMP 0
|
||||||
#define CMP_TYPE_TX_L2_COAL_CMP 2
|
|
||||||
#define CMP_TYPE_TX_L2_PTP_CMP 3
|
|
||||||
#define CMP_TYPE_RX_L2_TPA_START_V2_CMP 13
|
|
||||||
#define CMP_TYPE_RX_L2_V2_CMP 15
|
|
||||||
#define CMP_TYPE_RX_L2_CMP 17
|
#define CMP_TYPE_RX_L2_CMP 17
|
||||||
#define CMP_TYPE_RX_AGG_CMP 18
|
#define CMP_TYPE_RX_AGG_CMP 18
|
||||||
#define CMP_TYPE_RX_L2_TPA_START_CMP 19
|
#define CMP_TYPE_RX_L2_TPA_START_CMP 19
|
||||||
|
|
@ -199,12 +195,6 @@ struct rx_cmp {
|
||||||
#define RX_CMP_RSS_HASH_TYPE_SHIFT 9
|
#define RX_CMP_RSS_HASH_TYPE_SHIFT 9
|
||||||
#define RX_CMP_PAYLOAD_OFFSET (0xff << 16)
|
#define RX_CMP_PAYLOAD_OFFSET (0xff << 16)
|
||||||
#define RX_CMP_PAYLOAD_OFFSET_SHIFT 16
|
#define RX_CMP_PAYLOAD_OFFSET_SHIFT 16
|
||||||
#define RX_CMP_METADATA1 (0xf << 28)
|
|
||||||
#define RX_CMP_METADATA1_SHIFT 28
|
|
||||||
#define RX_CMP_METADATA1_TPID_SEL (0x7 << 28)
|
|
||||||
#define RX_CMP_METADATA1_TPID_8021Q (0x1 << 28)
|
|
||||||
#define RX_CMP_METADATA1_TPID_8021AD (0x0 << 28)
|
|
||||||
#define RX_CMP_METADATA1_VALID (0x8 << 28)
|
|
||||||
|
|
||||||
__le32 rx_cmp_rss_hash;
|
__le32 rx_cmp_rss_hash;
|
||||||
};
|
};
|
||||||
|
|
@ -218,23 +208,13 @@ struct rx_cmp {
|
||||||
(((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
|
(((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
|
||||||
RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
|
RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
|
||||||
|
|
||||||
#define RX_CMP_VLAN_VALID(rxcmp) \
|
|
||||||
((rxcmp)->rx_cmp_misc_v1 & cpu_to_le32(RX_CMP_METADATA1_VALID))
|
|
||||||
|
|
||||||
#define RX_CMP_VLAN_TPID_SEL(rxcmp) \
|
|
||||||
(le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_METADATA1_TPID_SEL)
|
|
||||||
|
|
||||||
struct rx_cmp_ext {
|
struct rx_cmp_ext {
|
||||||
__le32 rx_cmp_flags2;
|
__le32 rx_cmp_flags2;
|
||||||
#define RX_CMP_FLAGS2_IP_CS_CALC 0x1
|
#define RX_CMP_FLAGS2_IP_CS_CALC 0x1
|
||||||
#define RX_CMP_FLAGS2_L4_CS_CALC (0x1 << 1)
|
#define RX_CMP_FLAGS2_L4_CS_CALC (0x1 << 1)
|
||||||
#define RX_CMP_FLAGS2_T_IP_CS_CALC (0x1 << 2)
|
#define RX_CMP_FLAGS2_T_IP_CS_CALC (0x1 << 2)
|
||||||
#define RX_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3)
|
#define RX_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3)
|
||||||
#define RX_CMP_FLAGS2_CS_ALL_OK_MODE (0x1 << 3)
|
|
||||||
#define RX_CMP_FLAGS2_META_FORMAT_VLAN (0x1 << 4)
|
#define RX_CMP_FLAGS2_META_FORMAT_VLAN (0x1 << 4)
|
||||||
#define RX_CMP_FLAGS2_CS_OK_MASK (0x3f << 10)
|
|
||||||
#define RX_CMP_FLAGS2_L4_CS_OK_MASK (0x38 << 10)
|
|
||||||
#define RX_CMP_FLAGS2_CS_OK_SFT 10
|
|
||||||
__le32 rx_cmp_meta_data;
|
__le32 rx_cmp_meta_data;
|
||||||
#define RX_CMP_FLAGS2_METADATA_TCI_MASK 0xffff
|
#define RX_CMP_FLAGS2_METADATA_TCI_MASK 0xffff
|
||||||
#define RX_CMP_FLAGS2_METADATA_VID_MASK 0xfff
|
#define RX_CMP_FLAGS2_METADATA_VID_MASK 0xfff
|
||||||
|
|
@ -273,18 +253,8 @@ struct rx_cmp_ext {
|
||||||
#define RX_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL (0x7 << 12)
|
#define RX_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL (0x7 << 12)
|
||||||
#define RX_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN (0x8 << 12)
|
#define RX_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN (0x8 << 12)
|
||||||
|
|
||||||
#define RX_CMPL_V2_ERRORS_OT_PKT_ERROR_MASK (0x7 << 4)
|
|
||||||
#define RX_CMPL_V2_ERRORS_OT_PKT_L4_CS_ERROR (0x7 << 4)
|
|
||||||
#define RX_CMPL_V2_ERRORS_T_PKT_ERROR_MASK (0x7 << 9)
|
|
||||||
#define RX_CMPL_V2_ERRORS_T_PKT_L4_CS_ERROR (0x7 << 9)
|
|
||||||
#define RX_CMPL_V2_ERRORS_PKT_ERROR_MASK (0xf << 12)
|
|
||||||
#define RX_CMPL_V2_ERRORS_PKT_L4_CS_ERROR (0xa << 12)
|
|
||||||
|
|
||||||
#define RX_CMPL_CFA_CODE_MASK (0xffff << 16)
|
#define RX_CMPL_CFA_CODE_MASK (0xffff << 16)
|
||||||
#define RX_CMPL_CFA_CODE_SFT 16
|
#define RX_CMPL_CFA_CODE_SFT 16
|
||||||
#define RX_CMPL_METADATA0_MASK (0xffff << 16)
|
|
||||||
#define RX_CMPL_METADATA0_VID_MASK (0x0fff << 16)
|
|
||||||
#define RX_CMPL_METADATA0_SFT 16
|
|
||||||
|
|
||||||
__le32 rx_cmp_unused3;
|
__le32 rx_cmp_unused3;
|
||||||
};
|
};
|
||||||
|
|
@ -306,37 +276,10 @@ struct rx_cmp_ext {
|
||||||
((le32_to_cpu((rxcmp1)->rx_cmp_flags2) & \
|
((le32_to_cpu((rxcmp1)->rx_cmp_flags2) & \
|
||||||
RX_CMP_FLAGS2_T_L4_CS_CALC) >> 3)
|
RX_CMP_FLAGS2_T_L4_CS_CALC) >> 3)
|
||||||
|
|
||||||
#define RX_CMP_V2_L4_CS_OK(rxcmp1) \
|
|
||||||
(le32_to_cpu((rxcmp1)->rx_cmp_flags2) & RX_CMP_FLAGS2_L4_CS_OK_MASK)
|
|
||||||
|
|
||||||
#define RX_CMP_V2_L4_CS_OK_CNT(rxcmp1) \
|
|
||||||
(RX_CMP_V2_L4_CS_OK(rxcmp1) >> RX_CMP_FLAGS2_CS_OK_SFT)
|
|
||||||
|
|
||||||
#define RX_CMP_V2_OT_L4_CS_ERR(err) \
|
|
||||||
(((err) & RX_CMPL_V2_ERRORS_OT_PKT_ERROR_MASK) == \
|
|
||||||
RX_CMPL_V2_ERRORS_OT_PKT_L4_CS_ERROR)
|
|
||||||
|
|
||||||
#define RX_CMP_V2_T_L4_CS_ERR(err) \
|
|
||||||
(((err) & RX_CMPL_V2_ERRORS_T_PKT_ERROR_MASK) == \
|
|
||||||
RX_CMPL_V2_ERRORS_T_PKT_L4_CS_ERROR)
|
|
||||||
|
|
||||||
#define RX_CMP_V2_L4_CS_ERR(err) \
|
|
||||||
(((err) & RX_CMPL_V2_ERRORS_PKT_ERROR_MASK) == \
|
|
||||||
RX_CMPL_V2_ERRORS_PKT_L4_CS_ERROR)
|
|
||||||
|
|
||||||
#define RX_CMP_V2_L4_CS_ERRS(rxcmp1) ({ \
|
|
||||||
u32 __err = le32_to_cpu((rxcmp1)->rx_cmp_cfa_code_errors_v2); \
|
|
||||||
(RX_CMP_V2_OT_L4_CS_ERR(__err) || RX_CMP_V2_T_L4_CS_ERR(__err) ||\
|
|
||||||
RX_CMP_V2_L4_CS_ERR(__err)) ? 1 : 0; })
|
|
||||||
|
|
||||||
#define RX_CMP_CFA_CODE(rxcmpl1) \
|
#define RX_CMP_CFA_CODE(rxcmpl1) \
|
||||||
((le32_to_cpu((rxcmpl1)->rx_cmp_cfa_code_errors_v2) & \
|
((le32_to_cpu((rxcmpl1)->rx_cmp_cfa_code_errors_v2) & \
|
||||||
RX_CMPL_CFA_CODE_MASK) >> RX_CMPL_CFA_CODE_SFT)
|
RX_CMPL_CFA_CODE_MASK) >> RX_CMPL_CFA_CODE_SFT)
|
||||||
|
|
||||||
#define RX_CMP_METADATA0_VID(rxcmp1) \
|
|
||||||
((le32_to_cpu((rxcmp1)->rx_cmp_cfa_code_errors_v2) & \
|
|
||||||
RX_CMPL_METADATA0_VID_MASK) >> RX_CMPL_METADATA0_SFT)
|
|
||||||
|
|
||||||
struct rx_agg_cmp {
|
struct rx_agg_cmp {
|
||||||
__le32 rx_agg_cmp_len_flags_type;
|
__le32 rx_agg_cmp_len_flags_type;
|
||||||
#define RX_AGG_CMP_TYPE (0x3f << 0)
|
#define RX_AGG_CMP_TYPE (0x3f << 0)
|
||||||
|
|
@ -345,7 +288,7 @@ struct rx_agg_cmp {
|
||||||
u32 rx_agg_cmp_opaque;
|
u32 rx_agg_cmp_opaque;
|
||||||
__le32 rx_agg_cmp_v;
|
__le32 rx_agg_cmp_v;
|
||||||
#define RX_AGG_CMP_V (1 << 0)
|
#define RX_AGG_CMP_V (1 << 0)
|
||||||
#define RX_AGG_CMP_AGG_ID (0x0fff << 16)
|
#define RX_AGG_CMP_AGG_ID (0xffff << 16)
|
||||||
#define RX_AGG_CMP_AGG_ID_SHIFT 16
|
#define RX_AGG_CMP_AGG_ID_SHIFT 16
|
||||||
__le32 rx_agg_cmp_unused;
|
__le32 rx_agg_cmp_unused;
|
||||||
};
|
};
|
||||||
|
|
@ -381,10 +324,8 @@ struct rx_tpa_start_cmp {
|
||||||
#define RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT 9
|
#define RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT 9
|
||||||
#define RX_TPA_START_CMP_AGG_ID (0x7f << 25)
|
#define RX_TPA_START_CMP_AGG_ID (0x7f << 25)
|
||||||
#define RX_TPA_START_CMP_AGG_ID_SHIFT 25
|
#define RX_TPA_START_CMP_AGG_ID_SHIFT 25
|
||||||
#define RX_TPA_START_CMP_AGG_ID_P5 (0x0fff << 16)
|
#define RX_TPA_START_CMP_AGG_ID_P5 (0xffff << 16)
|
||||||
#define RX_TPA_START_CMP_AGG_ID_SHIFT_P5 16
|
#define RX_TPA_START_CMP_AGG_ID_SHIFT_P5 16
|
||||||
#define RX_TPA_START_CMP_METADATA1 (0xf << 28)
|
|
||||||
#define RX_TPA_START_CMP_METADATA1_SHIFT 28
|
|
||||||
|
|
||||||
__le32 rx_tpa_start_cmp_rss_hash;
|
__le32 rx_tpa_start_cmp_rss_hash;
|
||||||
};
|
};
|
||||||
|
|
@ -416,10 +357,6 @@ struct rx_tpa_start_cmp_ext {
|
||||||
#define RX_TPA_START_CMP_FLAGS2_L4_CS_CALC (0x1 << 1)
|
#define RX_TPA_START_CMP_FLAGS2_L4_CS_CALC (0x1 << 1)
|
||||||
#define RX_TPA_START_CMP_FLAGS2_T_IP_CS_CALC (0x1 << 2)
|
#define RX_TPA_START_CMP_FLAGS2_T_IP_CS_CALC (0x1 << 2)
|
||||||
#define RX_TPA_START_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3)
|
#define RX_TPA_START_CMP_FLAGS2_T_L4_CS_CALC (0x1 << 3)
|
||||||
#define RX_TPA_START_CMP_FLAGS2_CS_ALL_OK_MODE (0x1 << 3)
|
|
||||||
#define RX_TPA_START_CMP_FLAGS2_CS_OK_MASK (0x3f << 10)
|
|
||||||
#define RX_TPA_START_CMP_FLAGS2_L4_CS_OK_MASK (0x38 << 10)
|
|
||||||
#define RX_TPA_START_CMP_FLAGS2_CS_OK_SFT 10
|
|
||||||
#define RX_TPA_START_CMP_FLAGS2_IP_TYPE (0x1 << 8)
|
#define RX_TPA_START_CMP_FLAGS2_IP_TYPE (0x1 << 8)
|
||||||
#define RX_TPA_START_CMP_FLAGS2_CSUM_CMPL_VALID (0x1 << 9)
|
#define RX_TPA_START_CMP_FLAGS2_CSUM_CMPL_VALID (0x1 << 9)
|
||||||
#define RX_TPA_START_CMP_FLAGS2_EXT_META_FORMAT (0x3 << 10)
|
#define RX_TPA_START_CMP_FLAGS2_EXT_META_FORMAT (0x3 << 10)
|
||||||
|
|
@ -437,8 +374,6 @@ struct rx_tpa_start_cmp_ext {
|
||||||
#define RX_TPA_START_CMP_ERRORS_BUFFER_ERROR_FLUSH (0x5 << 1)
|
#define RX_TPA_START_CMP_ERRORS_BUFFER_ERROR_FLUSH (0x5 << 1)
|
||||||
#define RX_TPA_START_CMP_CFA_CODE (0xffff << 16)
|
#define RX_TPA_START_CMP_CFA_CODE (0xffff << 16)
|
||||||
#define RX_TPA_START_CMPL_CFA_CODE_SHIFT 16
|
#define RX_TPA_START_CMPL_CFA_CODE_SHIFT 16
|
||||||
#define RX_TPA_START_CMP_METADATA0_MASK (0xffff << 16)
|
|
||||||
#define RX_TPA_START_CMP_METADATA0_SFT 16
|
|
||||||
__le32 rx_tpa_start_cmp_hdr_info;
|
__le32 rx_tpa_start_cmp_hdr_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -650,9 +585,6 @@ struct nqe_cn {
|
||||||
#define DB_WCB_PAGE_SIZE 4096
|
#define DB_WCB_PAGE_SIZE 4096
|
||||||
#define DB_WCB_BUFFER_SIZE 256
|
#define DB_WCB_BUFFER_SIZE 256
|
||||||
|
|
||||||
#define DB_PPP_SIZE 256
|
|
||||||
#define DB_PPP_BD_OFFSET 16
|
|
||||||
|
|
||||||
#define INVALID_HW_RING_ID ((u16)-1)
|
#define INVALID_HW_RING_ID ((u16)-1)
|
||||||
|
|
||||||
/* The hardware supports certain page sizes. Use the supported page sizes
|
/* The hardware supports certain page sizes. Use the supported page sizes
|
||||||
|
|
@ -774,7 +706,37 @@ struct nqe_cn {
|
||||||
#define RING_CMP(idx) ((idx) & bp->cp_ring_mask)
|
#define RING_CMP(idx) ((idx) & bp->cp_ring_mask)
|
||||||
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
|
#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
|
||||||
|
|
||||||
|
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
|
||||||
|
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
|
||||||
#define DFLT_HWRM_CMD_TIMEOUT 500
|
#define DFLT_HWRM_CMD_TIMEOUT 500
|
||||||
|
#define SHORT_HWRM_CMD_TIMEOUT 20
|
||||||
|
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
|
||||||
|
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
|
||||||
|
#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12)
|
||||||
|
#define HWRM_RESP_ERR_CODE_MASK 0xffff
|
||||||
|
#define HWRM_RESP_LEN_OFFSET 4
|
||||||
|
#define HWRM_RESP_LEN_MASK 0xffff0000
|
||||||
|
#define HWRM_RESP_LEN_SFT 16
|
||||||
|
#define HWRM_RESP_VALID_MASK 0xff000000
|
||||||
|
#define BNXT_HWRM_REQ_MAX_SIZE 128
|
||||||
|
#define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \
|
||||||
|
BNXT_HWRM_REQ_MAX_SIZE)
|
||||||
|
#define HWRM_SHORT_MIN_TIMEOUT 3
|
||||||
|
#define HWRM_SHORT_MAX_TIMEOUT 10
|
||||||
|
#define HWRM_SHORT_TIMEOUT_COUNTER 5
|
||||||
|
|
||||||
|
#define HWRM_MIN_TIMEOUT 25
|
||||||
|
#define HWRM_MAX_TIMEOUT 40
|
||||||
|
|
||||||
|
#define HWRM_TOTAL_TIMEOUT(n) (((n) <= HWRM_SHORT_TIMEOUT_COUNTER) ? \
|
||||||
|
((n) * HWRM_SHORT_MIN_TIMEOUT) : \
|
||||||
|
(HWRM_SHORT_TIMEOUT_COUNTER * HWRM_SHORT_MIN_TIMEOUT + \
|
||||||
|
((n) - HWRM_SHORT_TIMEOUT_COUNTER) * HWRM_MIN_TIMEOUT))
|
||||||
|
|
||||||
|
#define HWRM_VALID_BIT_DELAY_USEC 150
|
||||||
|
|
||||||
|
#define BNXT_HWRM_CHNL_CHIMP 0
|
||||||
|
#define BNXT_HWRM_CHNL_KONG 1
|
||||||
|
|
||||||
#define BNXT_RX_EVENT 1
|
#define BNXT_RX_EVENT 1
|
||||||
#define BNXT_AGG_EVENT 2
|
#define BNXT_AGG_EVENT 2
|
||||||
|
|
@ -871,13 +833,6 @@ struct bnxt_db_info {
|
||||||
#define DB_RING_IDX(db, idx) (((idx) & (db)->db_ring_mask) | \
|
#define DB_RING_IDX(db, idx) (((idx) & (db)->db_ring_mask) | \
|
||||||
DB_EPOCH(db, idx))
|
DB_EPOCH(db, idx))
|
||||||
|
|
||||||
#define DB_PUSH_LEN(len) (DB_PUSH_INFO_PUSH_SIZE_MASK & \
|
|
||||||
(((sizeof(struct db_push_info) + \
|
|
||||||
sizeof(struct dbc_dbc)) / 8 + \
|
|
||||||
(len)) << DB_PUSH_INFO_PUSH_SIZE_SFT))
|
|
||||||
|
|
||||||
#define DB_PUSH_INFO(db, len, idx) (DB_PUSH_LEN(len) | DB_RING_IDX(db, idx))
|
|
||||||
|
|
||||||
struct bnxt_tx_ring_info {
|
struct bnxt_tx_ring_info {
|
||||||
struct bnxt_napi *bnapi;
|
struct bnxt_napi *bnapi;
|
||||||
u16 tx_prod;
|
u16 tx_prod;
|
||||||
|
|
@ -892,7 +847,10 @@ struct bnxt_tx_ring_info {
|
||||||
|
|
||||||
struct bnxt_db_info tx_push_db;
|
struct bnxt_db_info tx_push_db;
|
||||||
void __iomem *tx_push_wcb;
|
void __iomem *tx_push_wcb;
|
||||||
struct tx_push_buffer *tx_push;
|
union {
|
||||||
|
struct tx_push_buffer *tx_push;
|
||||||
|
struct tx_push_buffer_p5 *tx_push_p5;
|
||||||
|
};
|
||||||
dma_addr_t tx_push_mapping;
|
dma_addr_t tx_push_mapping;
|
||||||
__le64 data_mapping;
|
__le64 data_mapping;
|
||||||
|
|
||||||
|
|
@ -1026,32 +984,12 @@ struct bnxt_rx_ring_info {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bnxt_rx_sw_stats {
|
struct bnxt_sw_stats {
|
||||||
u64 rx_l4_csum_errors;
|
u64 rx_l4_csum_errors;
|
||||||
u64 rx_resets;
|
u64 rx_resets;
|
||||||
u64 rx_buf_errors;
|
u64 rx_buf_errors;
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_tx_sw_stats {
|
|
||||||
u64 tx_sw_errors;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_cmn_sw_stats {
|
|
||||||
u64 missed_irqs;
|
u64 missed_irqs;
|
||||||
};
|
u64 tx_sw_errors;
|
||||||
|
|
||||||
struct bnxt_sw_stats {
|
|
||||||
struct bnxt_rx_sw_stats rx;
|
|
||||||
struct bnxt_tx_sw_stats tx;
|
|
||||||
struct bnxt_cmn_sw_stats cmn;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_stats_mem {
|
|
||||||
u64 *sw_stats;
|
|
||||||
u64 *hw_masks;
|
|
||||||
void *hw_stats;
|
|
||||||
dma_addr_t hw_stats_map;
|
|
||||||
int len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bnxt_cp_ring_info {
|
struct bnxt_cp_ring_info {
|
||||||
|
|
@ -1078,7 +1016,8 @@ struct bnxt_cp_ring_info {
|
||||||
|
|
||||||
dma_addr_t cp_desc_mapping[MAX_CP_PAGES];
|
dma_addr_t cp_desc_mapping[MAX_CP_PAGES];
|
||||||
|
|
||||||
struct bnxt_stats_mem stats;
|
struct ctx_hw_stats *hw_stats;
|
||||||
|
dma_addr_t hw_stats_map;
|
||||||
u32 hw_stats_ctx_id;
|
u32 hw_stats_ctx_id;
|
||||||
|
|
||||||
struct bnxt_sw_stats sw_stats;
|
struct bnxt_sw_stats sw_stats;
|
||||||
|
|
@ -1163,16 +1102,6 @@ struct bnxt_vnic_info {
|
||||||
__le16 *rss_table;
|
__le16 *rss_table;
|
||||||
dma_addr_t rss_hash_key_dma_addr;
|
dma_addr_t rss_hash_key_dma_addr;
|
||||||
u64 *rss_hash_key;
|
u64 *rss_hash_key;
|
||||||
int rss_table_size;
|
|
||||||
#define BNXT_RSS_TABLE_ENTRIES_P5 64
|
|
||||||
#define BNXT_RSS_TABLE_SIZE_P5 (BNXT_RSS_TABLE_ENTRIES_P5 * 4)
|
|
||||||
#define BNXT_RSS_TABLE_MAX_TBL_P5 8
|
|
||||||
#define BNXT_MAX_RSS_TABLE_SIZE_P5 \
|
|
||||||
(BNXT_RSS_TABLE_SIZE_P5 * BNXT_RSS_TABLE_MAX_TBL_P5)
|
|
||||||
|
|
||||||
#define BNXT_MAX_RSS_TABLE_ENTRIES_P5 \
|
|
||||||
(BNXT_RSS_TABLE_ENTRIES_P5 * BNXT_RSS_TABLE_MAX_TBL_P5)
|
|
||||||
|
|
||||||
u32 rx_mask;
|
u32 rx_mask;
|
||||||
|
|
||||||
u8 *mc_list;
|
u8 *mc_list;
|
||||||
|
|
@ -1241,6 +1170,7 @@ struct bnxt_vf_info {
|
||||||
#define BNXT_VF_LINK_FORCED 0x4
|
#define BNXT_VF_LINK_FORCED 0x4
|
||||||
#define BNXT_VF_LINK_UP 0x8
|
#define BNXT_VF_LINK_UP 0x8
|
||||||
#define BNXT_VF_TRUST 0x10
|
#define BNXT_VF_TRUST 0x10
|
||||||
|
u32 func_flags; /* func cfg flags */
|
||||||
u32 min_tx_rate;
|
u32 min_tx_rate;
|
||||||
u32 max_tx_rate;
|
u32 max_tx_rate;
|
||||||
u16 min_tx_rings;
|
u16 min_tx_rings;
|
||||||
|
|
@ -1385,7 +1315,6 @@ struct bnxt_link_info {
|
||||||
#define BNXT_LINK_SPEED_100GB PORT_PHY_QCFG_RESP_LINK_SPEED_100GB
|
#define BNXT_LINK_SPEED_100GB PORT_PHY_QCFG_RESP_LINK_SPEED_100GB
|
||||||
#define BNXT_LINK_SPEED_200GB PORT_PHY_QCFG_RESP_LINK_SPEED_200GB
|
#define BNXT_LINK_SPEED_200GB PORT_PHY_QCFG_RESP_LINK_SPEED_200GB
|
||||||
u16 support_speeds;
|
u16 support_speeds;
|
||||||
u16 support_pam4_speeds;
|
|
||||||
u16 auto_link_speeds; /* fw adv setting */
|
u16 auto_link_speeds; /* fw adv setting */
|
||||||
#define BNXT_LINK_SPEED_MSK_100MB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100MB
|
#define BNXT_LINK_SPEED_MSK_100MB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100MB
|
||||||
#define BNXT_LINK_SPEED_MSK_1GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_1GB
|
#define BNXT_LINK_SPEED_MSK_1GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_1GB
|
||||||
|
|
@ -1397,16 +1326,10 @@ struct bnxt_link_info {
|
||||||
#define BNXT_LINK_SPEED_MSK_40GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_40GB
|
#define BNXT_LINK_SPEED_MSK_40GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_40GB
|
||||||
#define BNXT_LINK_SPEED_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_50GB
|
#define BNXT_LINK_SPEED_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_50GB
|
||||||
#define BNXT_LINK_SPEED_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100GB
|
#define BNXT_LINK_SPEED_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100GB
|
||||||
u16 auto_pam4_link_speeds;
|
#define BNXT_LINK_SPEED_MSK_200GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_200GB
|
||||||
#define BNXT_LINK_PAM4_SPEED_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_50G
|
|
||||||
#define BNXT_LINK_PAM4_SPEED_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_100G
|
|
||||||
#define BNXT_LINK_PAM4_SPEED_MSK_200GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_200G
|
|
||||||
u16 support_auto_speeds;
|
u16 support_auto_speeds;
|
||||||
u16 support_pam4_auto_speeds;
|
|
||||||
u16 lp_auto_link_speeds;
|
u16 lp_auto_link_speeds;
|
||||||
u16 lp_auto_pam4_link_speeds;
|
|
||||||
u16 force_link_speed;
|
u16 force_link_speed;
|
||||||
u16 force_pam4_link_speed;
|
|
||||||
u32 preemphasis;
|
u32 preemphasis;
|
||||||
u8 module_status;
|
u8 module_status;
|
||||||
u16 fec_cfg;
|
u16 fec_cfg;
|
||||||
|
|
@ -1418,14 +1341,10 @@ struct bnxt_link_info {
|
||||||
u8 autoneg;
|
u8 autoneg;
|
||||||
#define BNXT_AUTONEG_SPEED 1
|
#define BNXT_AUTONEG_SPEED 1
|
||||||
#define BNXT_AUTONEG_FLOW_CTRL 2
|
#define BNXT_AUTONEG_FLOW_CTRL 2
|
||||||
u8 req_signal_mode;
|
|
||||||
#define BNXT_SIG_MODE_NRZ PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_NRZ
|
|
||||||
#define BNXT_SIG_MODE_PAM4 PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_PAM4
|
|
||||||
u8 req_duplex;
|
u8 req_duplex;
|
||||||
u8 req_flow_ctrl;
|
u8 req_flow_ctrl;
|
||||||
u16 req_link_speed;
|
u16 req_link_speed;
|
||||||
u16 advertising; /* user adv setting */
|
u16 advertising; /* user adv setting */
|
||||||
u16 advertising_pam4;
|
|
||||||
bool force_link_chng;
|
bool force_link_chng;
|
||||||
|
|
||||||
bool phy_retry;
|
bool phy_retry;
|
||||||
|
|
@ -1606,7 +1525,6 @@ struct bnxt_ctx_mem_info {
|
||||||
u16 mrav_num_entries_units;
|
u16 mrav_num_entries_units;
|
||||||
u8 tqm_entries_multiple;
|
u8 tqm_entries_multiple;
|
||||||
u8 ctx_kind_initializer;
|
u8 ctx_kind_initializer;
|
||||||
u8 tqm_fp_rings_count;
|
|
||||||
|
|
||||||
u32 flags;
|
u32 flags;
|
||||||
#define BNXT_CTX_FLAG_INITED 0x01
|
#define BNXT_CTX_FLAG_INITED 0x01
|
||||||
|
|
@ -1640,7 +1558,6 @@ struct bnxt_fw_health {
|
||||||
u8 enabled:1;
|
u8 enabled:1;
|
||||||
u8 master:1;
|
u8 master:1;
|
||||||
u8 fatal:1;
|
u8 fatal:1;
|
||||||
u8 status_reliable:1;
|
|
||||||
u8 tmr_multiplier;
|
u8 tmr_multiplier;
|
||||||
u8 tmr_counter;
|
u8 tmr_counter;
|
||||||
u8 fw_reset_seq_cnt;
|
u8 fw_reset_seq_cnt;
|
||||||
|
|
@ -1668,31 +1585,9 @@ struct bnxt_fw_reporter_ctx {
|
||||||
#define BNXT_FW_HEALTH_WIN_BASE 0x3000
|
#define BNXT_FW_HEALTH_WIN_BASE 0x3000
|
||||||
#define BNXT_FW_HEALTH_WIN_MAP_OFF 8
|
#define BNXT_FW_HEALTH_WIN_MAP_OFF 8
|
||||||
|
|
||||||
#define BNXT_FW_HEALTH_WIN_OFF(reg) (BNXT_FW_HEALTH_WIN_BASE + \
|
|
||||||
((reg) & BNXT_GRC_OFFSET_MASK))
|
|
||||||
|
|
||||||
#define BNXT_FW_STATUS_HEALTHY 0x8000
|
#define BNXT_FW_STATUS_HEALTHY 0x8000
|
||||||
#define BNXT_FW_STATUS_SHUTDOWN 0x100000
|
#define BNXT_FW_STATUS_SHUTDOWN 0x100000
|
||||||
|
|
||||||
struct bnxt_oem_eem_req {
|
|
||||||
__le32 entry_num;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_oem_cmd_req {
|
|
||||||
__le32 req_type;
|
|
||||||
#define BNXT_OEM_CMD_TYPE_EEM_SYS_MEMORY 0x1
|
|
||||||
union {
|
|
||||||
struct bnxt_oem_eem_req eem_req;
|
|
||||||
} req;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bnxt_push_mode {
|
|
||||||
BNXT_PUSH_MODE_NONE = 0,
|
|
||||||
BNXT_PUSH_MODE_LEGACY, /* legacy silicon operation mode */
|
|
||||||
BNXT_PUSH_MODE_WCB, /* write combining supported on P5 silicon */
|
|
||||||
BNXT_PUSH_MODE_PPP, /* double buffered mode supported on SR2 */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt {
|
struct bnxt {
|
||||||
void __iomem *bar0;
|
void __iomem *bar0;
|
||||||
void __iomem *bar1;
|
void __iomem *bar1;
|
||||||
|
|
@ -1782,15 +1677,6 @@ struct bnxt {
|
||||||
#else
|
#else
|
||||||
#define BNXT_ASIC(bp) true
|
#define BNXT_ASIC(bp) true
|
||||||
#endif
|
#endif
|
||||||
#define BNXT_VPD_FLD_LEN 32
|
|
||||||
char board_partno[BNXT_VPD_FLD_LEN];
|
|
||||||
|
|
||||||
/* Must remain NULL for old bnxt_re upstream/
|
|
||||||
* inbox driver.
|
|
||||||
*/
|
|
||||||
void *reserved_ulp_kabi_0;
|
|
||||||
|
|
||||||
char board_serialno[BNXT_VPD_FLD_LEN];
|
|
||||||
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
|
|
@ -1857,14 +1743,12 @@ struct bnxt {
|
||||||
#define BNXT_CHIP_SR2(bp) \
|
#define BNXT_CHIP_SR2(bp) \
|
||||||
((bp)->chip_num == CHIP_NUM_58818)
|
((bp)->chip_num == CHIP_NUM_58818)
|
||||||
|
|
||||||
#define BNXT_CHIP_P5_THOR(bp) \
|
|
||||||
((bp)->chip_num == CHIP_NUM_57508 || \
|
|
||||||
(bp)->chip_num == CHIP_NUM_57504 || \
|
|
||||||
(bp)->chip_num == CHIP_NUM_57502)
|
|
||||||
|
|
||||||
/* Chip class phase 5 */
|
/* Chip class phase 5 */
|
||||||
#define BNXT_CHIP_P5(bp) \
|
#define BNXT_CHIP_P5(bp) \
|
||||||
(BNXT_CHIP_P5_THOR(bp) || BNXT_CHIP_SR2(bp))
|
((bp)->chip_num == CHIP_NUM_57508 || \
|
||||||
|
(bp)->chip_num == CHIP_NUM_57504 || \
|
||||||
|
(bp)->chip_num == CHIP_NUM_57502 || \
|
||||||
|
BNXT_CHIP_SR2(bp))
|
||||||
|
|
||||||
/* Chip class phase 4.x */
|
/* Chip class phase 4.x */
|
||||||
#define BNXT_CHIP_P4(bp) \
|
#define BNXT_CHIP_P4(bp) \
|
||||||
|
|
@ -1877,12 +1761,6 @@ struct bnxt {
|
||||||
#define BNXT_CHIP_P4_PLUS(bp) \
|
#define BNXT_CHIP_P4_PLUS(bp) \
|
||||||
(BNXT_CHIP_P4(bp) || BNXT_CHIP_P5(bp))
|
(BNXT_CHIP_P4(bp) || BNXT_CHIP_P5(bp))
|
||||||
|
|
||||||
#define BNXT_CHIP_SUPPORTS_PHY(bp) (BNXT_ASIC(bp) || BNXT_CHIP_SR2(bp))
|
|
||||||
/* Must remain NULL for new bnxt_re upstream/
|
|
||||||
* inbox driver.
|
|
||||||
*/
|
|
||||||
void *reserved_ulp_kabi_1;
|
|
||||||
|
|
||||||
struct bnxt_en_dev *edev;
|
struct bnxt_en_dev *edev;
|
||||||
/* The following 2 fields are for
|
/* The following 2 fields are for
|
||||||
* OOT compatibility checking only.
|
* OOT compatibility checking only.
|
||||||
|
|
@ -1901,10 +1779,6 @@ struct bnxt {
|
||||||
* bnxt_en and bnxt_re.
|
* bnxt_en and bnxt_re.
|
||||||
*/
|
*/
|
||||||
struct bnxt_en_dev * (*ulp_probe)(struct net_device *);
|
struct bnxt_en_dev * (*ulp_probe)(struct net_device *);
|
||||||
/* Do not add any fields before
|
|
||||||
* ulp_probe in both OOT and
|
|
||||||
* upstream/inbox drivers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct bnxt_napi **bnapi;
|
struct bnxt_napi **bnapi;
|
||||||
|
|
||||||
|
|
@ -1949,7 +1823,6 @@ struct bnxt {
|
||||||
int tx_nr_rings_xdp;
|
int tx_nr_rings_xdp;
|
||||||
|
|
||||||
int tx_wake_thresh;
|
int tx_wake_thresh;
|
||||||
enum bnxt_push_mode tx_push_mode;
|
|
||||||
int tx_push_thresh;
|
int tx_push_thresh;
|
||||||
int tx_push_size;
|
int tx_push_size;
|
||||||
|
|
||||||
|
|
@ -1964,8 +1837,6 @@ struct bnxt {
|
||||||
struct bnxt_vnic_info *vnic_info;
|
struct bnxt_vnic_info *vnic_info;
|
||||||
int nr_vnics;
|
int nr_vnics;
|
||||||
u32 rss_hash_cfg;
|
u32 rss_hash_cfg;
|
||||||
u16 *rss_indir_tbl;
|
|
||||||
u16 rss_indir_tbl_entries;
|
|
||||||
u8 usr_rss_hash_key[HW_HASH_KEY_SIZE];
|
u8 usr_rss_hash_key[HW_HASH_KEY_SIZE];
|
||||||
|
|
||||||
u16 max_mtu;
|
u16 max_mtu;
|
||||||
|
|
@ -2030,26 +1901,34 @@ struct bnxt {
|
||||||
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
|
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
|
||||||
#define BNXT_FW_CAP_HOT_RESET 0x00200000
|
#define BNXT_FW_CAP_HOT_RESET 0x00200000
|
||||||
#define BNXT_FW_CAP_SHARED_PORT_CFG 0x00400000
|
#define BNXT_FW_CAP_SHARED_PORT_CFG 0x00400000
|
||||||
#define BNXT_FW_CAP_CRASHDUMP 0x00800000
|
|
||||||
#define BNXT_FW_CAP_VLAN_RX_STRIP 0x01000000
|
|
||||||
#define BNXT_FW_CAP_VLAN_TX_INSERT 0x02000000
|
|
||||||
#define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED 0x04000000
|
|
||||||
#define BNXT_FW_CAP_CFA_EEM 0x08000000
|
|
||||||
|
|
||||||
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
|
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
|
||||||
u32 hwrm_spec_code;
|
u32 hwrm_spec_code;
|
||||||
u16 hwrm_cmd_seq;
|
u16 hwrm_cmd_seq;
|
||||||
u16 hwrm_cmd_kong_seq;
|
u16 hwrm_cmd_kong_seq;
|
||||||
struct dma_pool *hwrm_dma_pool;
|
u16 hwrm_intr_seq_id;
|
||||||
struct hlist_head hwrm_pending_list;
|
void *hwrm_short_cmd_req_addr;
|
||||||
|
dma_addr_t hwrm_short_cmd_req_dma_addr;
|
||||||
|
void *hwrm_cmd_resp_addr;
|
||||||
|
dma_addr_t hwrm_cmd_resp_dma_addr;
|
||||||
|
void *hwrm_cmd_kong_resp_addr;
|
||||||
|
dma_addr_t hwrm_cmd_kong_resp_dma_addr;
|
||||||
|
void *hwrm_dbg_resp_addr;
|
||||||
|
dma_addr_t hwrm_dbg_resp_dma_addr;
|
||||||
#define HWRM_DBG_REG_BUF_SIZE 128
|
#define HWRM_DBG_REG_BUF_SIZE 128
|
||||||
|
|
||||||
#ifdef NETDEV_GET_STATS64
|
#ifdef NETDEV_GET_STATS64
|
||||||
struct rtnl_link_stats64 net_stats_prev;
|
struct rtnl_link_stats64 net_stats_prev;
|
||||||
#endif
|
#endif
|
||||||
struct bnxt_stats_mem port_stats;
|
struct rx_port_stats *hw_rx_port_stats;
|
||||||
struct bnxt_stats_mem rx_port_stats_ext;
|
struct tx_port_stats *hw_tx_port_stats;
|
||||||
struct bnxt_stats_mem tx_port_stats_ext;
|
struct rx_port_stats_ext *hw_rx_port_stats_ext;
|
||||||
|
struct tx_port_stats_ext *hw_tx_port_stats_ext;
|
||||||
|
dma_addr_t hw_rx_port_stats_map;
|
||||||
|
dma_addr_t hw_tx_port_stats_map;
|
||||||
|
dma_addr_t hw_rx_port_stats_ext_map;
|
||||||
|
dma_addr_t hw_tx_port_stats_ext_map;
|
||||||
|
int hw_port_stats_size;
|
||||||
u16 fw_rx_stats_ext_size;
|
u16 fw_rx_stats_ext_size;
|
||||||
u16 fw_tx_stats_ext_size;
|
u16 fw_tx_stats_ext_size;
|
||||||
u16 hw_ring_stats_size;
|
u16 hw_ring_stats_size;
|
||||||
|
|
@ -2065,12 +1944,6 @@ struct bnxt {
|
||||||
#define BC_HWRM_STR_LEN 21
|
#define BC_HWRM_STR_LEN 21
|
||||||
#define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN)
|
#define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN)
|
||||||
char fw_ver_str[FW_VER_STR_LEN];
|
char fw_ver_str[FW_VER_STR_LEN];
|
||||||
char hwrm_ver_supp[FW_VER_STR_LEN];
|
|
||||||
u64 fw_ver_code;
|
|
||||||
#define BNXT_FW_VER_CODE(maj, min, bld, rsv) \
|
|
||||||
((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv))
|
|
||||||
#define BNXT_FW_MAJ(bp) ((bp)->fw_ver_code >> 48)
|
|
||||||
|
|
||||||
__be16 vxlan_port;
|
__be16 vxlan_port;
|
||||||
u8 vxlan_port_cnt;
|
u8 vxlan_port_cnt;
|
||||||
__le16 vxlan_fw_dst_port_id;
|
__le16 vxlan_fw_dst_port_id;
|
||||||
|
|
@ -2114,7 +1987,6 @@ struct bnxt {
|
||||||
#define BNXT_FW_EXCEPTION_SP_EVENT 19
|
#define BNXT_FW_EXCEPTION_SP_EVENT 19
|
||||||
#define BNXT_VF_VNIC_CHANGE_SP_EVENT 20
|
#define BNXT_VF_VNIC_CHANGE_SP_EVENT 20
|
||||||
#define BNXT_LINK_CFG_CHANGE_SP_EVENT 21
|
#define BNXT_LINK_CFG_CHANGE_SP_EVENT 21
|
||||||
#define BNXT_PTP_CURRENT_TIME_EVENT 22
|
|
||||||
|
|
||||||
struct delayed_work fw_reset_task;
|
struct delayed_work fw_reset_task;
|
||||||
int fw_reset_state;
|
int fw_reset_state;
|
||||||
|
|
@ -2223,34 +2095,17 @@ struct bnxt {
|
||||||
struct list_head tc_indr_block_list;
|
struct list_head tc_indr_block_list;
|
||||||
struct notifier_block tc_netdev_nb;
|
struct notifier_block tc_netdev_nb;
|
||||||
#endif
|
#endif
|
||||||
struct bnxt_eem_info *eem_info;
|
|
||||||
void *dmabuf_data;
|
|
||||||
struct dentry *debugfs_pdev;
|
struct dentry *debugfs_pdev;
|
||||||
struct dentry *debugfs_dim;
|
struct dentry *debugfs_dim;
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BNXT_GET_RING_STATS64(sw, counter) \
|
|
||||||
(*((sw) + offsetof(struct ctx_hw_stats, counter) / 8))
|
|
||||||
|
|
||||||
#define BNXT_GET_RX_PORT_STATS64(sw, counter) \
|
|
||||||
(*((sw) + offsetof(struct rx_port_stats, counter) / 8))
|
|
||||||
|
|
||||||
#define BNXT_GET_TX_PORT_STATS64(sw, counter) \
|
|
||||||
(*((sw) + offsetof(struct tx_port_stats, counter) / 8))
|
|
||||||
|
|
||||||
#define BNXT_PORT_STATS_SIZE \
|
|
||||||
(sizeof(struct rx_port_stats) + sizeof(struct tx_port_stats) + 1024)
|
|
||||||
|
|
||||||
#define BNXT_TX_PORT_STATS_BYTE_OFFSET \
|
|
||||||
(sizeof(struct rx_port_stats) + 512)
|
|
||||||
|
|
||||||
#define BNXT_RX_STATS_OFFSET(counter) \
|
#define BNXT_RX_STATS_OFFSET(counter) \
|
||||||
(offsetof(struct rx_port_stats, counter) / 8)
|
(offsetof(struct rx_port_stats, counter) / 8)
|
||||||
|
|
||||||
#define BNXT_TX_STATS_OFFSET(counter) \
|
#define BNXT_TX_STATS_OFFSET(counter) \
|
||||||
((offsetof(struct tx_port_stats, counter) + \
|
((offsetof(struct tx_port_stats, counter) + \
|
||||||
BNXT_TX_PORT_STATS_BYTE_OFFSET) / 8)
|
sizeof(struct rx_port_stats) + 512) / 8)
|
||||||
|
|
||||||
#define BNXT_RX_STATS_EXT_OFFSET(counter) \
|
#define BNXT_RX_STATS_EXT_OFFSET(counter) \
|
||||||
(offsetof(struct rx_port_stats_ext, counter) / 8)
|
(offsetof(struct rx_port_stats_ext, counter) / 8)
|
||||||
|
|
@ -2258,11 +2113,6 @@ struct bnxt {
|
||||||
#define BNXT_TX_STATS_EXT_OFFSET(counter) \
|
#define BNXT_TX_STATS_EXT_OFFSET(counter) \
|
||||||
(offsetof(struct tx_port_stats_ext, counter) / 8)
|
(offsetof(struct tx_port_stats_ext, counter) / 8)
|
||||||
|
|
||||||
#define BNXT_HW_FEATURE_VLAN_ALL_RX \
|
|
||||||
(NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)
|
|
||||||
#define BNXT_HW_FEATURE_VLAN_ALL_TX \
|
|
||||||
(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX)
|
|
||||||
|
|
||||||
#ifdef BNXT_PRIV_RX_BUSY_POLL
|
#ifdef BNXT_PRIV_RX_BUSY_POLL
|
||||||
static inline void bnxt_enable_poll(struct bnxt_napi *bnapi)
|
static inline void bnxt_enable_poll(struct bnxt_napi *bnapi)
|
||||||
{
|
{
|
||||||
|
|
@ -2431,18 +2281,77 @@ static inline void bnxt_db_write(struct bnxt *bp, struct bnxt_db_info *db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool bnxt_cfa_hwrm_message(u16 req_type)
|
||||||
|
{
|
||||||
|
switch (req_type) {
|
||||||
|
case HWRM_CFA_ENCAP_RECORD_ALLOC:
|
||||||
|
case HWRM_CFA_ENCAP_RECORD_FREE:
|
||||||
|
case HWRM_CFA_DECAP_FILTER_ALLOC:
|
||||||
|
case HWRM_CFA_DECAP_FILTER_FREE:
|
||||||
|
case HWRM_CFA_EM_FLOW_ALLOC:
|
||||||
|
case HWRM_CFA_EM_FLOW_FREE:
|
||||||
|
case HWRM_CFA_EM_FLOW_CFG:
|
||||||
|
case HWRM_CFA_FLOW_ALLOC:
|
||||||
|
case HWRM_CFA_FLOW_FREE:
|
||||||
|
case HWRM_CFA_FLOW_INFO:
|
||||||
|
case HWRM_CFA_FLOW_FLUSH:
|
||||||
|
case HWRM_CFA_FLOW_STATS:
|
||||||
|
case HWRM_CFA_METER_PROFILE_ALLOC:
|
||||||
|
case HWRM_CFA_METER_PROFILE_FREE:
|
||||||
|
case HWRM_CFA_METER_PROFILE_CFG:
|
||||||
|
case HWRM_CFA_METER_INSTANCE_ALLOC:
|
||||||
|
case HWRM_CFA_METER_INSTANCE_FREE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool bnxt_kong_hwrm_message(struct bnxt *bp, struct input *req)
|
||||||
|
{
|
||||||
|
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
|
||||||
|
bnxt_cfa_hwrm_message(le16_to_cpu(req->req_type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool bnxt_hwrm_kong_chnl(struct bnxt *bp, struct input *req)
|
||||||
|
{
|
||||||
|
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
|
||||||
|
req->resp_addr == cpu_to_le64(bp->hwrm_cmd_kong_resp_dma_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *bnxt_get_hwrm_resp_addr(struct bnxt *bp, void *req)
|
||||||
|
{
|
||||||
|
if (bnxt_hwrm_kong_chnl(bp, (struct input *)req))
|
||||||
|
return bp->hwrm_cmd_kong_resp_addr;
|
||||||
|
else
|
||||||
|
return bp->hwrm_cmd_resp_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 bnxt_get_hwrm_seq_id(struct bnxt *bp, u16 dst)
|
||||||
|
{
|
||||||
|
u16 seq_id;
|
||||||
|
|
||||||
|
if (dst == BNXT_HWRM_CHNL_CHIMP)
|
||||||
|
seq_id = bp->hwrm_cmd_seq++;
|
||||||
|
else
|
||||||
|
seq_id = bp->hwrm_cmd_kong_seq++;
|
||||||
|
return seq_id;
|
||||||
|
}
|
||||||
|
|
||||||
extern const u16 bnxt_lhint_arr[];
|
extern const u16 bnxt_lhint_arr[];
|
||||||
extern const struct pci_device_id bnxt_pci_tbl[];
|
extern const struct pci_device_id bnxt_pci_tbl[];
|
||||||
|
|
||||||
int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp, struct bnxt_ctx_pg_info *ctx_pg,
|
|
||||||
u32 mem_size, u8 depth, bool use_init_val);
|
|
||||||
void bnxt_free_ctx_pg_tbls(struct bnxt *bp, struct bnxt_ctx_pg_info *ctx_pg);
|
|
||||||
int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||||
u16 prod, gfp_t gfp);
|
u16 prod, gfp_t gfp);
|
||||||
void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data);
|
void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data);
|
||||||
void bnxt_set_tpa_flags(struct bnxt *bp);
|
void bnxt_set_tpa_flags(struct bnxt *bp);
|
||||||
void bnxt_set_ring_params(struct bnxt *);
|
void bnxt_set_ring_params(struct bnxt *);
|
||||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
||||||
|
void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16);
|
||||||
|
int _hwrm_send_message(struct bnxt *, void *, u32, int);
|
||||||
|
int _hwrm_send_message_silent(struct bnxt *, void *, u32, int);
|
||||||
|
int hwrm_send_message(struct bnxt *, void *, u32, int);
|
||||||
|
int hwrm_send_message_silent(struct bnxt *, void *, u32, int);
|
||||||
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
|
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
|
||||||
int bmap_size, bool async_only);
|
int bmap_size, bool async_only);
|
||||||
void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr);
|
void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr);
|
||||||
|
|
@ -2456,7 +2365,6 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
|
||||||
int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
|
int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
|
||||||
struct bnxt_ntuple_filter *fltr);
|
struct bnxt_ntuple_filter *fltr);
|
||||||
void bnxt_fill_ipv6_mask(__be32 mask[4]);
|
void bnxt_fill_ipv6_mask(__be32 mask[4]);
|
||||||
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
|
|
||||||
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
|
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
|
||||||
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
|
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
|
||||||
int bnxt_nq_rings_in_use(struct bnxt *bp);
|
int bnxt_nq_rings_in_use(struct bnxt *bp);
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,7 @@
|
||||||
#include <net/flow_keys.h>
|
#include <net/flow_keys.h>
|
||||||
#endif
|
#endif
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/dma-buf.h>
|
|
||||||
#ifdef HAVE_IEEE1588_SUPPORT
|
|
||||||
#include <linux/ptp_clock_kernel.h>
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_TC_FLOW_CLS_OFFLOAD) || defined(HAVE_TC_CLS_FLOWER_OFFLOAD)
|
#if defined(HAVE_TC_FLOW_CLS_OFFLOAD) || defined(HAVE_TC_CLS_FLOWER_OFFLOAD)
|
||||||
#include <net/pkt_cls.h>
|
#include <net/pkt_cls.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -45,11 +42,8 @@
|
||||||
|
|
||||||
#if !IS_ENABLED(CONFIG_NET_DEVLINK)
|
#if !IS_ENABLED(CONFIG_NET_DEVLINK)
|
||||||
#undef HAVE_DEVLINK
|
#undef HAVE_DEVLINK
|
||||||
#undef HAVE_DEVLINK_INFO
|
|
||||||
#undef HAVE_DEVLINK_PARAM
|
#undef HAVE_DEVLINK_PARAM
|
||||||
#undef HAVE_NDO_DEVLINK_PORT
|
#undef HAVE_NDO_DEVLINK_PORT
|
||||||
#undef HAVE_DEVLINK_PORT_PARAM
|
|
||||||
#undef HAVE_DEVLINK_FLASH_UPDATE
|
|
||||||
#undef HAVE_DEVLINK_HEALTH_REPORT
|
#undef HAVE_DEVLINK_HEALTH_REPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -311,29 +305,6 @@
|
||||||
dma_unmap_page(dev, dma_addr, size, dir)
|
dma_unmap_page(dev, dma_addr, size, dir)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline struct dma_buf *dma_buf_export_attr(void *priv, int pg_count,
|
|
||||||
const struct dma_buf_ops *ops)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_DMA_EXPORT
|
|
||||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
|
||||||
|
|
||||||
exp_info.ops = ops;
|
|
||||||
exp_info.size = pg_count << PAGE_SHIFT;
|
|
||||||
exp_info.flags = O_RDWR;
|
|
||||||
exp_info.priv = priv;
|
|
||||||
exp_info.exp_name = "eem_dma_buf";
|
|
||||||
return dma_buf_export(&exp_info);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DMA_EXPORT_FLAG_RESV
|
|
||||||
return dma_buf_export(priv, ops, pg_count << PAGE_SHIFT, O_RDWR, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DMA_EXPORT_FLAG
|
|
||||||
return dma_buf_export(priv, ops, pg_count << PAGE_SHIFT, O_RDWR);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef RHEL_RELEASE_VERSION
|
#ifndef RHEL_RELEASE_VERSION
|
||||||
#define RHEL_RELEASE_VERSION(a, b) 0
|
#define RHEL_RELEASE_VERSION(a, b) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -372,11 +343,6 @@ static inline struct dma_buf *dma_buf_export_attr(void *priv, int pg_count,
|
||||||
#define ndo_set_vf_trust extended.ndo_set_vf_trust
|
#define ndo_set_vf_trust extended.ndo_set_vf_trust
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NDO_UDP_TUNNEL_RH
|
|
||||||
#define ndo_udp_tunnel_add extended.ndo_udp_tunnel_add
|
|
||||||
#define ndo_udp_tunnel_del extended.ndo_udp_tunnel_del
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_TC_SETUP_QDISC_MQPRIO
|
#ifndef HAVE_TC_SETUP_QDISC_MQPRIO
|
||||||
#define TC_SETUP_QDISC_MQPRIO TC_SETUP_MQPRIO
|
#define TC_SETUP_QDISC_MQPRIO TC_SETUP_MQPRIO
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -436,10 +402,6 @@ struct ethtool_eee {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_ETHTOOL_RESET_CRASHDUMP
|
|
||||||
enum compat_ethtool_reset_flags { ETH_RESET_CRASHDUMP = 1 << 9 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_SKB_FRAG_PAGE
|
#ifndef HAVE_SKB_FRAG_PAGE
|
||||||
static inline struct page *skb_frag_page(const skb_frag_t *frag)
|
static inline struct page *skb_frag_page(const skb_frag_t *frag)
|
||||||
{
|
{
|
||||||
|
|
@ -532,15 +494,6 @@ skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type)
|
||||||
#undef CONFIG_RFS_ACCEL
|
#undef CONFIG_RFS_ACCEL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_RFS_ACCEL
|
|
||||||
#if !defined(HAVE_FLOW_HASH_FROM_KEYS) && !defined(HAVE_GET_HASH_RAW)
|
|
||||||
static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return skb->rxhash;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* CONFIG_RFS_ACCEL */
|
|
||||||
|
|
||||||
#if !defined(IEEE_8021QAZ_APP_SEL_DGRAM) || !defined(CONFIG_DCB) || !defined(HAVE_IEEE_DELAPP)
|
#if !defined(IEEE_8021QAZ_APP_SEL_DGRAM) || !defined(CONFIG_DCB) || !defined(HAVE_IEEE_DELAPP)
|
||||||
#undef CONFIG_BNXT_DCB
|
#undef CONFIG_BNXT_DCB
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -711,23 +664,6 @@ static inline const char *netdev_name(const struct net_device *dev)
|
||||||
dev_warn(dev, format, ##args)
|
dev_warn(dev, format, ##args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef netdev_level_once
|
|
||||||
#define netdev_level_once(level, dev, fmt, ...) \
|
|
||||||
do { \
|
|
||||||
static bool __print_once __read_mostly; \
|
|
||||||
\
|
|
||||||
if (!__print_once) { \
|
|
||||||
__print_once = true; \
|
|
||||||
netdev_printk(level, dev, fmt, ##__VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define netdev_info_once(dev, fmt, ...) \
|
|
||||||
netdev_level_once(KERN_INFO, dev, fmt, ##__VA_ARGS__)
|
|
||||||
#define netdev_warn_once(dev, fmt, ...) \
|
|
||||||
netdev_level_once(KERN_WARNING, dev, fmt, ##__VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef netdev_uc_count
|
#ifndef netdev_uc_count
|
||||||
#define netdev_uc_count(dev) ((dev)->uc.count)
|
#define netdev_uc_count(dev) ((dev)->uc.count)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -762,14 +698,6 @@ do { \
|
||||||
#define writeq_relaxed(v, a) writeq(v, a)
|
#define writeq_relaxed(v, a) writeq(v, a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WRITE_ONCE
|
|
||||||
#define WRITE_ONCE(x, val) (x = val)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef READ_ONCE
|
|
||||||
#define READ_ONCE(val) (val)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||||
#include <net/busy_poll.h>
|
#include <net/busy_poll.h>
|
||||||
#if defined(HAVE_NAPI_HASH_ADD) && defined(NETDEV_BUSY_POLL)
|
#if defined(HAVE_NAPI_HASH_ADD) && defined(NETDEV_BUSY_POLL)
|
||||||
|
|
@ -785,21 +713,6 @@ do { \
|
||||||
#undef HAVE_IEEE1588_SUPPORT
|
#undef HAVE_IEEE1588_SUPPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_PTP_GETTIMEX64)
|
|
||||||
struct ptp_system_timestamp {
|
|
||||||
struct timespec64 pre_ts;
|
|
||||||
struct timespec64 post_ts;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RHEL_RELEASE_CODE) && (RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(7,0))
|
#if defined(RHEL_RELEASE_CODE) && (RHEL_RELEASE_CODE == RHEL_RELEASE_VERSION(7,0))
|
||||||
#undef CONFIG_CRASH_DUMP
|
#undef CONFIG_CRASH_DUMP
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -960,15 +873,6 @@ static inline int netif_get_num_default_rss_queues(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef IFF_RXFH_CONFIGURED
|
|
||||||
#define IFF_RXFH_CONFIGURED 0
|
|
||||||
#undef HAVE_SET_RXFH
|
|
||||||
static inline bool netif_is_rxfh_configured(const struct net_device *dev)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(HAVE_TCP_V6_CHECK)
|
#if !defined(HAVE_TCP_V6_CHECK)
|
||||||
static __inline__ __sum16 tcp_v6_check(int len,
|
static __inline__ __sum16 tcp_v6_check(int len,
|
||||||
const struct in6_addr *saddr,
|
const struct in6_addr *saddr,
|
||||||
|
|
@ -1039,22 +943,6 @@ static inline void *kmalloc_array(unsigned n, size_t s, gfp_t gfp)
|
||||||
#define ETH_MODULE_SFF_8636_LEN 256
|
#define ETH_MODULE_SFF_8636_LEN 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_MSIX_RANGE
|
|
||||||
static inline int
|
|
||||||
pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
|
|
||||||
int minvec, int maxvec)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
while (maxvec >= minvec) {
|
|
||||||
rc = pci_enable_msix(dev, entries, maxvec);
|
|
||||||
if (!rc || rc < 0)
|
|
||||||
return rc;
|
|
||||||
maxvec = rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* HAVE_MSIX_RANGE */
|
|
||||||
|
|
||||||
#ifndef HAVE_PCI_PHYSFN
|
#ifndef HAVE_PCI_PHYSFN
|
||||||
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
|
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
|
|
@ -1079,23 +967,16 @@ enum pci_bus_speed {
|
||||||
PCIE_SPEED_2_5GT = 0x14,
|
PCIE_SPEED_2_5GT = 0x14,
|
||||||
PCIE_SPEED_5_0GT = 0x15,
|
PCIE_SPEED_5_0GT = 0x15,
|
||||||
PCIE_SPEED_8_0GT = 0x16,
|
PCIE_SPEED_8_0GT = 0x16,
|
||||||
#ifndef PCIE_SPEED_16_0GT
|
|
||||||
PCIE_SPEED_16_0GT = 0x17,
|
|
||||||
#endif
|
|
||||||
PCI_SPEED_UNKNOWN = 0xFF,
|
PCI_SPEED_UNKNOWN = 0xFF,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PCIE_SPEED_16_0GT
|
|
||||||
#define PCIE_SPEED_16_0GT 0x17
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const unsigned char pcie_link_speed[] = {
|
static const unsigned char pcie_link_speed[] = {
|
||||||
PCI_SPEED_UNKNOWN, /* 0 */
|
PCI_SPEED_UNKNOWN, /* 0 */
|
||||||
PCIE_SPEED_2_5GT, /* 1 */
|
PCIE_SPEED_2_5GT, /* 1 */
|
||||||
PCIE_SPEED_5_0GT, /* 2 */
|
PCIE_SPEED_5_0GT, /* 2 */
|
||||||
PCIE_SPEED_8_0GT, /* 3 */
|
PCIE_SPEED_8_0GT, /* 3 */
|
||||||
PCIE_SPEED_16_0GT, /* 4 */
|
PCI_SPEED_UNKNOWN, /* 4 */
|
||||||
PCI_SPEED_UNKNOWN, /* 5 */
|
PCI_SPEED_UNKNOWN, /* 5 */
|
||||||
PCI_SPEED_UNKNOWN, /* 6 */
|
PCI_SPEED_UNKNOWN, /* 6 */
|
||||||
PCI_SPEED_UNKNOWN, /* 7 */
|
PCI_SPEED_UNKNOWN, /* 7 */
|
||||||
|
|
@ -1123,10 +1004,6 @@ static const unsigned char pcie_link_speed[] = {
|
||||||
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */
|
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PCI_EXP_LNKCAP2_SLS_16_0GB
|
|
||||||
#define PCI_EXP_LNKCAP2_SLS_16_0GB 0x00000010 /* Supported Speed 16GT/s */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PCI_EXP_LNKCAP_SLS_2_5GB
|
#ifndef PCI_EXP_LNKCAP_SLS_2_5GB
|
||||||
#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0*/
|
#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0*/
|
||||||
#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1*/
|
#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1*/
|
||||||
|
|
@ -1136,23 +1013,17 @@ static const unsigned char pcie_link_speed[] = {
|
||||||
#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit2 */
|
#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit2 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PCI_EXP_LNKCAP_SLS_16_0GB
|
|
||||||
#define PCI_EXP_LNKCAP_SLS_16_0GB 0x00000004 /* LNKCAP2 SLS Vector bit 3 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PCIE_SPEED2STR
|
#ifndef PCIE_SPEED2STR
|
||||||
/* PCIe link information */
|
/* PCIe link information */
|
||||||
#define PCIE_SPEED2STR(speed) \
|
#define PCIE_SPEED2STR(speed) \
|
||||||
((speed) == PCIE_SPEED_16_0GT ? "16 GT/s" : \
|
((speed) == PCIE_SPEED_8_0GT ? "8 GT/s" : \
|
||||||
(speed) == PCIE_SPEED_8_0GT ? "8 GT/s" : \
|
|
||||||
(speed) == PCIE_SPEED_5_0GT ? "5 GT/s" : \
|
(speed) == PCIE_SPEED_5_0GT ? "5 GT/s" : \
|
||||||
(speed) == PCIE_SPEED_2_5GT ? "2.5 GT/s" : \
|
(speed) == PCIE_SPEED_2_5GT ? "2.5 GT/s" : \
|
||||||
"Unknown speed")
|
"Unknown speed")
|
||||||
|
|
||||||
/* PCIe speed to Mb/s reduced by encoding overhead */
|
/* PCIe speed to Mb/s reduced by encoding overhead */
|
||||||
#define PCIE_SPEED2MBS_ENC(speed) \
|
#define PCIE_SPEED2MBS_ENC(speed) \
|
||||||
((speed) == PCIE_SPEED_16_0GT ? 16000 * 128 / 130 : \
|
((speed) == PCIE_SPEED_8_0GT ? 8000 * 128 / 130 : \
|
||||||
(speed) == PCIE_SPEED_8_0GT ? 8000 * 128 / 130 : \
|
|
||||||
(speed) == PCIE_SPEED_5_0GT ? 5000 * 8 / 10 : \
|
(speed) == PCIE_SPEED_5_0GT ? 5000 * 8 / 10 : \
|
||||||
(speed) == PCIE_SPEED_2_5GT ? 2500 * 8 / 10 : \
|
(speed) == PCIE_SPEED_2_5GT ? 2500 * 8 / 10 : \
|
||||||
0)
|
0)
|
||||||
|
|
@ -1243,9 +1114,7 @@ static enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
|
||||||
pci_read_config_word(dev, BNXT_PCIE_CAP + PCI_EXP_LNKCAP2, &lnkcap2);
|
pci_read_config_word(dev, BNXT_PCIE_CAP + PCI_EXP_LNKCAP2, &lnkcap2);
|
||||||
#endif
|
#endif
|
||||||
if (lnkcap2) { /* PCIe r3.0-compliant */
|
if (lnkcap2) { /* PCIe r3.0-compliant */
|
||||||
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB)
|
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
|
||||||
return PCIE_SPEED_16_0GT;
|
|
||||||
else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
|
|
||||||
return PCIE_SPEED_8_0GT;
|
return PCIE_SPEED_8_0GT;
|
||||||
else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
|
else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
|
||||||
return PCIE_SPEED_5_0GT;
|
return PCIE_SPEED_5_0GT;
|
||||||
|
|
@ -1260,9 +1129,7 @@ static enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
|
||||||
pci_read_config_word(dev, BNXT_PCIE_CAP + PCI_EXP_LNKCAP, &lnkcap);
|
pci_read_config_word(dev, BNXT_PCIE_CAP + PCI_EXP_LNKCAP, &lnkcap);
|
||||||
#endif
|
#endif
|
||||||
if (lnkcap) {
|
if (lnkcap) {
|
||||||
if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB)
|
if (lnkcap & PCI_EXP_LNKCAP_SLS_8_0GB)
|
||||||
return PCIE_SPEED_16_0GT;
|
|
||||||
else if (lnkcap & PCI_EXP_LNKCAP_SLS_8_0GB)
|
|
||||||
return PCIE_SPEED_8_0GT;
|
return PCIE_SPEED_8_0GT;
|
||||||
else if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
|
else if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
|
||||||
return PCIE_SPEED_5_0GT;
|
return PCIE_SPEED_5_0GT;
|
||||||
|
|
@ -1337,32 +1204,6 @@ static inline bool pci_is_bridge(struct pci_dev *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_PCI_GET_DSN
|
|
||||||
static inline u64 pci_get_dsn(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
u32 dword;
|
|
||||||
u64 dsn;
|
|
||||||
int pos;
|
|
||||||
|
|
||||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN);
|
|
||||||
if (!pos)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The Device Serial Number is two dwords offset 4 bytes from the
|
|
||||||
* capability position. The specification says that the first dword is
|
|
||||||
* the lower half, and the second dword is the upper half.
|
|
||||||
*/
|
|
||||||
pos += 4;
|
|
||||||
pci_read_config_dword(dev, pos, &dword);
|
|
||||||
dsn = (u64)dword;
|
|
||||||
pci_read_config_dword(dev, pos + 4, &dword);
|
|
||||||
dsn |= ((u64)dword) << 32;
|
|
||||||
|
|
||||||
return dsn;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_NDO_XDP
|
#ifndef HAVE_NDO_XDP
|
||||||
struct netdev_bpf;
|
struct netdev_bpf;
|
||||||
struct xdp_buff;
|
struct xdp_buff;
|
||||||
|
|
@ -1663,112 +1504,16 @@ static inline void devlink_flash_update_status_notify(struct devlink *devlink,
|
||||||
#define DEVLINK_INFO_VERSION_GENERIC_ASIC_REV "asic.rev"
|
#define DEVLINK_INFO_VERSION_GENERIC_ASIC_REV "asic.rev"
|
||||||
#define DEVLINK_INFO_VERSION_GENERIC_FW "fw"
|
#define DEVLINK_INFO_VERSION_GENERIC_FW "fw"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_MGMT
|
||||||
|
#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT "fw.mgmt"
|
||||||
|
#endif
|
||||||
|
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_APP
|
||||||
|
#define DEVLINK_INFO_VERSION_GENERIC_FW_APP "fw.app"
|
||||||
|
#endif
|
||||||
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_PSID
|
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_PSID
|
||||||
#define DEVLINK_INFO_VERSION_GENERIC_FW_PSID "fw.psid"
|
#define DEVLINK_INFO_VERSION_GENERIC_FW_PSID "fw.psid"
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_ROCE
|
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_ROCE
|
||||||
#define DEVLINK_INFO_VERSION_GENERIC_FW_ROCE "fw.roce"
|
#define DEVLINK_INFO_VERSION_GENERIC_FW_ROCE "fw.roce"
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API
|
|
||||||
#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API "fw.mgmt.api"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_DEVLINK_INFO_BSN_PUT
|
|
||||||
static inline int devlink_info_board_serial_number_put(struct devlink_info_req *req,
|
|
||||||
const char *bsn)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_DEVLINK_INFO */
|
#endif /* HAVE_DEVLINK_INFO */
|
||||||
|
|
||||||
#ifndef HAVE_PCIE_FLR
|
|
||||||
static inline int pcie_flr(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
|
||||||
|
|
||||||
msleep(100);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* pcie_flr */
|
|
||||||
|
|
||||||
#if defined(HAVE_FLOW_OFFLOAD_H) && \
|
|
||||||
!defined(HAVE_FLOW_ACTION_BASIC_HW_STATS_CHECK)
|
|
||||||
static inline bool
|
|
||||||
flow_action_basic_hw_stats_check(const struct flow_action *action,
|
|
||||||
struct netlink_ext_ack *extack)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define flow_stats_update(flow_stats, bytes, pkts, last_used, used_hw_stats) \
|
|
||||||
flow_stats_update(flow_stats, bytes, pkts, last_used)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef fallthrough
|
|
||||||
#define fallthrough do {} while (0) /* fall through */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __ALIGN_KERNEL_MASK
|
|
||||||
#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
|
||||||
#endif
|
|
||||||
#ifndef __ALIGN_KERNEL
|
|
||||||
#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
|
|
||||||
#endif
|
|
||||||
#ifndef ALIGN_DOWN
|
|
||||||
#define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct bnxt_compat_dma_pool {
|
|
||||||
struct dma_pool *pool;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct bnxt_compat_dma_pool*
|
|
||||||
bnxt_compat_dma_pool_create(const char *name, struct device *dev, size_t size,
|
|
||||||
size_t align, size_t allocation)
|
|
||||||
{
|
|
||||||
struct bnxt_compat_dma_pool *wrapper;
|
|
||||||
|
|
||||||
wrapper = kmalloc_node(sizeof(*wrapper), GFP_KERNEL, dev_to_node(dev));
|
|
||||||
if (!wrapper)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
wrapper->pool = dma_pool_create(name, dev, size, align, allocation);
|
|
||||||
wrapper->size = size;
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bnxt_compat_dma_pool_destroy(struct bnxt_compat_dma_pool *wrapper)
|
|
||||||
{
|
|
||||||
dma_pool_destroy(wrapper->pool);
|
|
||||||
kfree(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
bnxt_compat_dma_pool_alloc(struct bnxt_compat_dma_pool *wrapper,
|
|
||||||
gfp_t mem_flags, dma_addr_t *handle)
|
|
||||||
{
|
|
||||||
void *mem;
|
|
||||||
|
|
||||||
mem = dma_pool_alloc(wrapper->pool, mem_flags & ~__GFP_ZERO, handle);
|
|
||||||
if (mem_flags & __GFP_ZERO)
|
|
||||||
memset(mem, 0, wrapper->size);
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
bnxt_compat_dma_pool_free(struct bnxt_compat_dma_pool *wrapper, void *vaddr,
|
|
||||||
dma_addr_t addr)
|
|
||||||
{
|
|
||||||
dma_pool_free(wrapper->pool, vaddr, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define dma_pool_create bnxt_compat_dma_pool_create
|
|
||||||
#define dma_pool_destroy bnxt_compat_dma_pool_destroy
|
|
||||||
#define dma_pool_alloc bnxt_compat_dma_pool_alloc
|
|
||||||
#define dma_pool_free bnxt_compat_dma_pool_free
|
|
||||||
#define dma_pool bnxt_compat_dma_pool
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,9 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/log2.h>
|
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_dcb.h"
|
#include "bnxt_dcb.h"
|
||||||
|
|
||||||
#ifdef CONFIG_BNXT_DCB
|
#ifdef CONFIG_BNXT_DCB
|
||||||
|
|
@ -40,42 +38,38 @@ static int bnxt_queue_to_tc(struct bnxt *bp, u8 queue_id)
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_pri2cos_cfg(struct bnxt *bp, struct ieee_ets *ets)
|
static int bnxt_hwrm_queue_pri2cos_cfg(struct bnxt *bp, struct ieee_ets *ets)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_pri2cos_cfg_input *req;
|
struct hwrm_queue_pri2cos_cfg_input req = {0};
|
||||||
u8 *pri2cos;
|
u8 *pri2cos;
|
||||||
int rc, i;
|
int i;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PRI2COS_CFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PRI2COS_CFG, -1, -1);
|
||||||
if (rc)
|
req.flags = cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_FLAGS_PATH_BIDIR |
|
||||||
return rc;
|
QUEUE_PRI2COS_CFG_REQ_FLAGS_IVLAN);
|
||||||
|
|
||||||
req->flags = cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_FLAGS_PATH_BIDIR |
|
pri2cos = &req.pri0_cos_queue_id;
|
||||||
QUEUE_PRI2COS_CFG_REQ_FLAGS_IVLAN);
|
|
||||||
|
|
||||||
pri2cos = &req->pri0_cos_queue_id;
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
||||||
u8 qidx;
|
u8 qidx;
|
||||||
|
|
||||||
req->enables |= cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_ENABLES_PRI0_COS_QUEUE_ID << i);
|
req.enables |= cpu_to_le32(
|
||||||
|
QUEUE_PRI2COS_CFG_REQ_ENABLES_PRI0_COS_QUEUE_ID << i);
|
||||||
|
|
||||||
qidx = bp->tc_to_qidx[ets->prio_tc[i]];
|
qidx = bp->tc_to_qidx[ets->prio_tc[i]];
|
||||||
pri2cos[i] = bp->q_info[qidx].queue_id;
|
pri2cos[i] = bp->q_info[qidx].queue_id;
|
||||||
}
|
}
|
||||||
return hwrm_req_send(bp, req);
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_pri2cos_qcfg_output *resp;
|
struct hwrm_queue_pri2cos_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_queue_pri2cos_qcfg_input *req;
|
struct hwrm_queue_pri2cos_qcfg_input req = {0};
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PRI2COS_QCFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PRI2COS_QCFG, -1, -1);
|
||||||
if (rc)
|
req.flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN);
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
resp = hwrm_req_hold(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
u8 *pri2cos = &resp->pri0_cos_queue_id;
|
u8 *pri2cos = &resp->pri0_cos_queue_id;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -89,27 +83,25 @@ static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
||||||
ets->prio_tc[i] = tc;
|
ets->prio_tc[i] = tc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
|
static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
|
||||||
u8 max_tc)
|
u8 max_tc)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_cos2bw_cfg_input *req;
|
struct hwrm_queue_cos2bw_cfg_input req = {0};
|
||||||
struct bnxt_cos2bw_cfg cos2bw;
|
struct bnxt_cos2bw_cfg cos2bw;
|
||||||
void *data;
|
void *data;
|
||||||
int rc, i;
|
int i;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_CFG);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_COS2BW_CFG, -1, -1);
|
||||||
for (i = 0; i < max_tc; i++) {
|
for (i = 0; i < max_tc; i++) {
|
||||||
u8 qidx = bp->tc_to_qidx[i];
|
u8 qidx = bp->tc_to_qidx[i];
|
||||||
|
|
||||||
req->enables |=
|
req.enables |= cpu_to_le32(
|
||||||
cpu_to_le32(QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID << qidx);
|
QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID <<
|
||||||
|
qidx);
|
||||||
|
|
||||||
memset(&cos2bw, 0, sizeof(cos2bw));
|
memset(&cos2bw, 0, sizeof(cos2bw));
|
||||||
cos2bw.queue_id = bp->q_info[qidx].queue_id;
|
cos2bw.queue_id = bp->q_info[qidx].queue_id;
|
||||||
|
|
@ -128,32 +120,30 @@ static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
|
||||||
cpu_to_le32((ets->tc_tx_bw[i] * 100) |
|
cpu_to_le32((ets->tc_tx_bw[i] * 100) |
|
||||||
BW_VALUE_UNIT_PERCENT1_100);
|
BW_VALUE_UNIT_PERCENT1_100);
|
||||||
}
|
}
|
||||||
data = &req->unused_0 + qidx * (sizeof(cos2bw) - 4);
|
data = &req.unused_0 + qidx * (sizeof(cos2bw) - 4);
|
||||||
memcpy(data, &cos2bw.queue_id, sizeof(cos2bw) - 4);
|
memcpy(data, &cos2bw.queue_id, sizeof(cos2bw) - 4);
|
||||||
if (qidx == 0) {
|
if (qidx == 0) {
|
||||||
req->queue_id0 = cos2bw.queue_id;
|
req.queue_id0 = cos2bw.queue_id;
|
||||||
req->unused_0 = 0;
|
req.unused_0 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hwrm_req_send(bp, req);
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_cos2bw_qcfg_output *resp;
|
struct hwrm_queue_cos2bw_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_queue_cos2bw_qcfg_input *req;
|
struct hwrm_queue_cos2bw_qcfg_input req = {0};
|
||||||
struct bnxt_cos2bw_cfg cos2bw;
|
struct bnxt_cos2bw_cfg cos2bw;
|
||||||
void *data;
|
void *data;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_QCFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_COS2BW_QCFG, -1, -1);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +167,7 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
|
||||||
ets->tc_tx_bw[tc] = cos2bw.bw_weight;
|
ets->tc_tx_bw[tc] = cos2bw.bw_weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,12 +229,11 @@ static int bnxt_queue_remap(struct bnxt *bp, unsigned int lltc_mask)
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_pfc_cfg(struct bnxt *bp, struct ieee_pfc *pfc)
|
static int bnxt_hwrm_queue_pfc_cfg(struct bnxt *bp, struct ieee_pfc *pfc)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_pfcenable_cfg_input *req;
|
struct hwrm_queue_pfcenable_cfg_input req = {0};
|
||||||
struct ieee_ets *my_ets = bp->ieee_ets;
|
struct ieee_ets *my_ets = bp->ieee_ets;
|
||||||
unsigned int tc_mask = 0, pri_mask = 0;
|
unsigned int tc_mask = 0, pri_mask = 0;
|
||||||
u8 i, pri, lltc_count = 0;
|
u8 i, pri, lltc_count = 0;
|
||||||
bool need_q_remap = false;
|
bool need_q_remap = false;
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!my_ets)
|
if (!my_ets)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -277,43 +266,38 @@ static int bnxt_hwrm_queue_pfc_cfg(struct bnxt *bp, struct ieee_pfc *pfc)
|
||||||
if (need_q_remap)
|
if (need_q_remap)
|
||||||
bnxt_queue_remap(bp, tc_mask);
|
bnxt_queue_remap(bp, tc_mask);
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCENABLE_CFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PFCENABLE_CFG, -1, -1);
|
||||||
if (rc)
|
req.flags = cpu_to_le32(pri_mask);
|
||||||
return rc;
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
|
|
||||||
req->flags = cpu_to_le32(pri_mask);
|
|
||||||
return hwrm_req_send(bp, req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt *bp, struct ieee_pfc *pfc)
|
static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt *bp, struct ieee_pfc *pfc)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_pfcenable_qcfg_output *resp;
|
struct hwrm_queue_pfcenable_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_queue_pfcenable_qcfg_input *req;
|
struct hwrm_queue_pfcenable_qcfg_input req = {0};
|
||||||
u8 pri_mask;
|
u8 pri_mask;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCENABLE_QCFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PFCENABLE_QCFG, -1, -1);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pri_mask = le32_to_cpu(resp->flags);
|
pri_mask = le32_to_cpu(resp->flags);
|
||||||
pfc->pfc_en = pri_mask;
|
pfc->pfc_en = pri_mask;
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_set_dcbx_app(struct bnxt *bp, struct dcb_app *app,
|
static int bnxt_hwrm_set_dcbx_app(struct bnxt *bp, struct dcb_app *app,
|
||||||
bool add)
|
bool add)
|
||||||
{
|
{
|
||||||
struct hwrm_fw_set_structured_data_input *set;
|
struct hwrm_fw_set_structured_data_input set = {0};
|
||||||
struct hwrm_fw_get_structured_data_input *get;
|
struct hwrm_fw_get_structured_data_input get = {0};
|
||||||
struct hwrm_struct_data_dcbx_app *fw_app;
|
struct hwrm_struct_data_dcbx_app *fw_app;
|
||||||
struct hwrm_struct_hdr *data;
|
struct hwrm_struct_hdr *data;
|
||||||
dma_addr_t mapping;
|
dma_addr_t mapping;
|
||||||
|
|
@ -323,26 +307,19 @@ static int bnxt_hwrm_set_dcbx_app(struct bnxt *bp, struct dcb_app *app,
|
||||||
if (bp->hwrm_spec_code < 0x10601)
|
if (bp->hwrm_spec_code < 0x10601)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, get, HWRM_FW_GET_STRUCTURED_DATA);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
hwrm_req_hold(bp, get);
|
|
||||||
hwrm_req_alloc_flags(bp, get, GFP_KERNEL | __GFP_ZERO);
|
|
||||||
|
|
||||||
n = IEEE_8021QAZ_MAX_TCS;
|
n = IEEE_8021QAZ_MAX_TCS;
|
||||||
data_len = sizeof(*data) + sizeof(*fw_app) * n;
|
data_len = sizeof(*data) + sizeof(*fw_app) * n;
|
||||||
data = hwrm_req_dma_slice(bp, get, data_len, &mapping);
|
data = dma_zalloc_coherent(&bp->pdev->dev, data_len, &mapping,
|
||||||
if (!data) {
|
GFP_KERNEL);
|
||||||
rc = -ENOMEM;
|
if (!data)
|
||||||
goto set_app_exit;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
get->dest_data_addr = cpu_to_le64(mapping);
|
bnxt_hwrm_cmd_hdr_init(bp, &get, HWRM_FW_GET_STRUCTURED_DATA, -1, -1);
|
||||||
get->structure_id = cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP);
|
get.dest_data_addr = cpu_to_le64(mapping);
|
||||||
get->subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
get.structure_id = cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP);
|
||||||
get->count = 0;
|
get.subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
||||||
rc = hwrm_req_send(bp, get);
|
get.count = 0;
|
||||||
|
rc = hwrm_send_message(bp, &get, sizeof(get), HWRM_CMD_TIMEOUT);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto set_app_exit;
|
goto set_app_exit;
|
||||||
|
|
||||||
|
|
@ -388,49 +365,44 @@ static int bnxt_hwrm_set_dcbx_app(struct bnxt *bp, struct dcb_app *app,
|
||||||
data->len = cpu_to_le16(sizeof(*fw_app) * n);
|
data->len = cpu_to_le16(sizeof(*fw_app) * n);
|
||||||
data->subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
data->subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, set, HWRM_FW_SET_STRUCTURED_DATA);
|
bnxt_hwrm_cmd_hdr_init(bp, &set, HWRM_FW_SET_STRUCTURED_DATA, -1, -1);
|
||||||
if (rc)
|
set.src_data_addr = cpu_to_le64(mapping);
|
||||||
goto set_app_exit;
|
set.data_len = cpu_to_le16(sizeof(*data) + sizeof(*fw_app) * n);
|
||||||
|
set.hdr_cnt = 1;
|
||||||
set->src_data_addr = cpu_to_le64(mapping);
|
rc = hwrm_send_message(bp, &set, sizeof(set), HWRM_CMD_TIMEOUT);
|
||||||
set->data_len = cpu_to_le16(sizeof(*data) + sizeof(*fw_app) * n);
|
|
||||||
set->hdr_cnt = 1;
|
|
||||||
rc = hwrm_req_send(bp, set);
|
|
||||||
|
|
||||||
set_app_exit:
|
set_app_exit:
|
||||||
hwrm_req_drop(bp, get); /* dropping get request and associated slice */
|
dma_free_coherent(&bp->pdev->dev, data_len, data, mapping);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_dscp_qcaps(struct bnxt *bp)
|
static int bnxt_hwrm_queue_dscp_qcaps(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_dscp_qcaps_output *resp;
|
struct hwrm_queue_dscp_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_queue_dscp_qcaps_input *req;
|
struct hwrm_queue_dscp_qcaps_input req = {0};
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
bp->max_dscp_value = 0;
|
bp->max_dscp_value = 0;
|
||||||
if (bp->hwrm_spec_code < 0x10800 || BNXT_VF(bp))
|
if (bp->hwrm_spec_code < 0x10800 || BNXT_VF(bp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_DSCP_QCAPS);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_DSCP_QCAPS, -1, -1);
|
||||||
if (rc)
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
rc = _hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send_silent(bp, req);
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
bp->max_dscp_value = (1 << resp->num_dscp_bits) - 1;
|
bp->max_dscp_value = (1 << resp->num_dscp_bits) - 1;
|
||||||
if (bp->max_dscp_value < 0x3f)
|
if (bp->max_dscp_value < 0x3f)
|
||||||
bp->max_dscp_value = 0;
|
bp->max_dscp_value = 0;
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app,
|
static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app,
|
||||||
bool add)
|
bool add)
|
||||||
{
|
{
|
||||||
struct hwrm_queue_dscp2pri_cfg_input *req;
|
struct hwrm_queue_dscp2pri_cfg_input req = {0};
|
||||||
struct bnxt_dscp2pri_entry *dscp2pri;
|
struct bnxt_dscp2pri_entry *dscp2pri;
|
||||||
dma_addr_t mapping;
|
dma_addr_t mapping;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
@ -438,25 +410,23 @@ static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app,
|
||||||
if (bp->hwrm_spec_code < 0x10800)
|
if (bp->hwrm_spec_code < 0x10800)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_QUEUE_DSCP2PRI_CFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_DSCP2PRI_CFG, -1, -1);
|
||||||
if (rc)
|
dscp2pri = dma_alloc_coherent(&bp->pdev->dev, sizeof(*dscp2pri),
|
||||||
return rc;
|
&mapping, GFP_KERNEL);
|
||||||
|
if (!dscp2pri)
|
||||||
dscp2pri = hwrm_req_dma_slice(bp, req, sizeof(*dscp2pri), &mapping);
|
|
||||||
if (!dscp2pri) {
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
req->src_data_addr = cpu_to_le64(mapping);
|
req.src_data_addr = cpu_to_le64(mapping);
|
||||||
dscp2pri->dscp = app->protocol;
|
dscp2pri->dscp = app->protocol;
|
||||||
if (add)
|
if (add)
|
||||||
dscp2pri->mask = 0x3f;
|
dscp2pri->mask = 0x3f;
|
||||||
else
|
else
|
||||||
dscp2pri->mask = 0;
|
dscp2pri->mask = 0;
|
||||||
dscp2pri->pri = app->priority;
|
dscp2pri->pri = app->priority;
|
||||||
req->entry_cnt = cpu_to_le16(1);
|
req.entry_cnt = cpu_to_le16(1);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
|
dma_free_coherent(&bp->pdev->dev, sizeof(*dscp2pri), dscp2pri,
|
||||||
|
mapping);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,26 +472,24 @@ static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets)
|
||||||
{
|
{
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
struct ieee_ets *my_ets = bp->ieee_ets;
|
struct ieee_ets *my_ets = bp->ieee_ets;
|
||||||
int rc;
|
|
||||||
|
|
||||||
ets->ets_cap = bp->max_tc;
|
ets->ets_cap = bp->max_tc;
|
||||||
|
|
||||||
if (!my_ets) {
|
if (!my_ets) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (bp->dcbx_cap & DCB_CAP_DCBX_HOST)
|
if (bp->dcbx_cap & DCB_CAP_DCBX_HOST)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL);
|
my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL);
|
||||||
if (!my_ets)
|
if (!my_ets)
|
||||||
return -ENOMEM;
|
return 0;
|
||||||
rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets);
|
rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
return 0;
|
||||||
rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets);
|
rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
return 0;
|
||||||
|
|
||||||
/* cache result */
|
|
||||||
bp->ieee_ets = my_ets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ets->cbs = my_ets->cbs;
|
ets->cbs = my_ets->cbs;
|
||||||
|
|
@ -530,9 +498,6 @@ static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets)
|
||||||
memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
|
memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
|
||||||
memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
|
memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
|
||||||
kfree(my_ets);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
|
static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
|
||||||
|
|
@ -574,7 +539,7 @@ static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
|
||||||
static int bnxt_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc)
|
static int bnxt_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc)
|
||||||
{
|
{
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
__le64 *stats = bp->port_stats.hw_stats;
|
__le64 *stats = (__le64 *)bp->hw_rx_port_stats;
|
||||||
struct ieee_pfc *my_pfc = bp->ieee_pfc;
|
struct ieee_pfc *my_pfc = bp->ieee_pfc;
|
||||||
long rx_off, tx_off;
|
long rx_off, tx_off;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
@ -702,59 +667,6 @@ static int bnxt_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __bnxt_del_roce_app(struct bnxt *bp, struct dcb_app *app)
|
|
||||||
{
|
|
||||||
u32 prio_mask = dcb_ieee_getapp_mask(bp->dev, app);
|
|
||||||
|
|
||||||
if (!prio_mask)
|
|
||||||
return;
|
|
||||||
|
|
||||||
app->priority = ilog2(prio_mask);
|
|
||||||
dcb_ieee_delapp(bp->dev, app);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_del_roce_apps(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
struct dcb_app app;
|
|
||||||
|
|
||||||
if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
|
|
||||||
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
|
||||||
return;
|
|
||||||
|
|
||||||
app.selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE;
|
|
||||||
app.protocol = ETH_P_ROCE;
|
|
||||||
__bnxt_del_roce_app(bp, &app);
|
|
||||||
|
|
||||||
app.selector = IEEE_8021QAZ_APP_SEL_DGRAM;
|
|
||||||
app.protocol = ROCE_V2_UDP_DPORT;
|
|
||||||
__bnxt_del_roce_app(bp, &app);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_del_dscp_apps(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_DSCP_MASK_MAP
|
|
||||||
struct dcb_ieee_app_prio_map dscp_map;
|
|
||||||
struct dcb_app app;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
|
|
||||||
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
|
|
||||||
return;
|
|
||||||
|
|
||||||
app.selector = IEEE_8021QAZ_APP_SEL_DSCP;
|
|
||||||
dcb_ieee_getapp_prio_dscp_mask_map(bp->dev, &dscp_map);
|
|
||||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
|
||||||
for (j = 0; j < 64; j++) {
|
|
||||||
if (dscp_map.map[i] & (1ULL << j)) {
|
|
||||||
app.protocol = j;
|
|
||||||
app.priority = i;
|
|
||||||
dcb_ieee_delapp(bp->dev, &app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 bnxt_dcbnl_getdcbx(struct net_device *dev)
|
static u8 bnxt_dcbnl_getdcbx(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
|
|
@ -813,16 +725,12 @@ void bnxt_dcb_init(struct bnxt *bp)
|
||||||
bp->dev->dcbnl_ops = &dcbnl_ops;
|
bp->dev->dcbnl_ops = &dcbnl_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bnxt_dcb_free(struct bnxt *bp, bool reset)
|
void bnxt_dcb_free(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
kfree(bp->ieee_pfc);
|
kfree(bp->ieee_pfc);
|
||||||
kfree(bp->ieee_ets);
|
kfree(bp->ieee_ets);
|
||||||
bp->ieee_pfc = NULL;
|
bp->ieee_pfc = NULL;
|
||||||
bp->ieee_ets = NULL;
|
bp->ieee_ets = NULL;
|
||||||
if (reset) {
|
|
||||||
bnxt_del_roce_apps(bp);
|
|
||||||
bnxt_del_dscp_apps(bp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -831,7 +739,7 @@ void bnxt_dcb_init(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void bnxt_dcb_free(struct bnxt *bp, bool reset)
|
void bnxt_dcb_free(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,6 @@ struct bnxt_dscp2pri_entry {
|
||||||
|
|
||||||
#define HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL 0x0300
|
#define HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL 0x0300
|
||||||
|
|
||||||
void bnxt_dcb_init(struct bnxt *bp);
|
void bnxt_dcb_init(struct bnxt *);
|
||||||
void bnxt_dcb_free(struct bnxt *bp, bool reset);
|
void bnxt_dcb_free(struct bnxt *);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_vfr.h"
|
#include "bnxt_vfr.h"
|
||||||
#include "bnxt_devlink.h"
|
#include "bnxt_devlink.h"
|
||||||
#include "bnxt_ethtool.h"
|
#include "bnxt_ethtool.h"
|
||||||
|
|
@ -26,36 +25,25 @@ static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
|
||||||
union bnxt_nvm_data *src,
|
union bnxt_nvm_data *src,
|
||||||
int nvm_num_bits, int dl_num_bytes);
|
int nvm_num_bits, int dl_num_bytes);
|
||||||
|
|
||||||
static int bnxt_hwrm_nvm_get_var(struct bnxt *bp, dma_addr_t data_dma_addr,
|
static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp,
|
||||||
u16 offset, u16 num_bits)
|
union devlink_param_value *nvm_cfg_ver)
|
||||||
{
|
|
||||||
struct hwrm_nvm_get_variable_input *req;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->dest_data_addr = cpu_to_le64(data_dma_addr);
|
|
||||||
req->option_num = cpu_to_le16(offset);
|
|
||||||
req->data_len = cpu_to_le16(num_bits);
|
|
||||||
return hwrm_req_send_silent(bp, req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_get_nvm_cfg_ver(struct bnxt *bp,
|
|
||||||
union devlink_param_value *nvm_cfg_ver)
|
|
||||||
{
|
{
|
||||||
|
struct hwrm_nvm_get_variable_input req = {0};
|
||||||
union bnxt_nvm_data *data;
|
union bnxt_nvm_data *data;
|
||||||
dma_addr_t data_dma_addr;
|
dma_addr_t data_dma_addr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_GET_VARIABLE, -1, -1);
|
||||||
data = dma_zalloc_coherent(&bp->pdev->dev, sizeof(*data),
|
data = dma_zalloc_coherent(&bp->pdev->dev, sizeof(*data),
|
||||||
&data_dma_addr, GFP_KERNEL);
|
&data_dma_addr, GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rc = bnxt_hwrm_nvm_get_var(bp, data_dma_addr, NVM_OFF_NVM_CFG_VER,
|
req.dest_data_addr = cpu_to_le64(data_dma_addr);
|
||||||
BNXT_NVM_CFG_VER_BITS);
|
req.data_len = cpu_to_le16(BNXT_NVM_CFG_VER_BITS);
|
||||||
|
req.option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER);
|
||||||
|
|
||||||
|
rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
bnxt_copy_from_nvm_data(nvm_cfg_ver, data,
|
bnxt_copy_from_nvm_data(nvm_cfg_ver, data,
|
||||||
BNXT_NVM_CFG_VER_BITS,
|
BNXT_NVM_CFG_VER_BITS,
|
||||||
|
|
@ -81,20 +69,6 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (strlen(bp->board_partno)) {
|
|
||||||
rc = devlink_info_version_fixed_put(req,
|
|
||||||
DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
|
|
||||||
bp->board_partno);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(bp->board_serialno)) {
|
|
||||||
rc = devlink_info_board_serial_number_put(req, bp->board_serialno);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(buf, "%X", bp->chip_num);
|
sprintf(buf, "%X", bp->chip_num);
|
||||||
rc = devlink_info_version_fixed_put(req,
|
rc = devlink_info_version_fixed_put(req,
|
||||||
DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
|
DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
|
||||||
|
|
@ -117,13 +91,6 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(bp->board_serialno)) {
|
|
||||||
rc = devlink_info_version_fixed_put(req, "vpd.serialno",
|
|
||||||
bp->board_serialno);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(ver_resp->active_pkg_name)) {
|
if (strlen(ver_resp->active_pkg_name)) {
|
||||||
rc =
|
rc =
|
||||||
devlink_info_version_running_put(req,
|
devlink_info_version_running_put(req,
|
||||||
|
|
@ -133,7 +100,7 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BNXT_PF(bp) && !bnxt_get_nvm_cfg_ver(bp, &nvm_cfg_ver)) {
|
if (BNXT_PF(bp) && !bnxt_hwrm_get_nvm_cfg_ver(bp, &nvm_cfg_ver)) {
|
||||||
u32 ver = nvm_cfg_ver.vu32;
|
u32 ver = nvm_cfg_ver.vu32;
|
||||||
|
|
||||||
sprintf(buf, "%X.%X.%X", (ver >> 16) & 0xF, (ver >> 8) & 0xF,
|
sprintf(buf, "%X.%X.%X", (ver >> 16) & 0xF, (ver >> 8) & 0xF,
|
||||||
|
|
@ -170,19 +137,13 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||||
ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b);
|
ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b);
|
||||||
}
|
}
|
||||||
rc = devlink_info_version_running_put(req,
|
rc = devlink_info_version_running_put(req,
|
||||||
DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, fw_ver);
|
DEVLINK_INFO_VERSION_GENERIC_FW_APP, fw_ver);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = devlink_info_version_running_put(req,
|
|
||||||
DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
|
|
||||||
bp->hwrm_ver_supp);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
|
if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
|
||||||
rc = devlink_info_version_running_put(req,
|
rc = devlink_info_version_running_put(req,
|
||||||
DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, mgmt_ver);
|
DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
@ -327,27 +288,6 @@ struct devlink_health_reporter_ops bnxt_dl_fw_fatal_reporter_ops = {
|
||||||
.recover = bnxt_fw_fatal_recover,
|
.recover = bnxt_fw_fatal_recover,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct devlink_health_reporter *
|
|
||||||
__bnxt_dl_reporter_create(struct bnxt *bp,
|
|
||||||
const struct devlink_health_reporter_ops *ops)
|
|
||||||
{
|
|
||||||
struct devlink_health_reporter *reporter;
|
|
||||||
|
|
||||||
#ifndef HAVE_DEVLINK_HEALTH_AUTO_RECOVER
|
|
||||||
reporter = devlink_health_reporter_create(bp->dl, ops, 0, bp);
|
|
||||||
#else
|
|
||||||
reporter = devlink_health_reporter_create(bp->dl, ops, 0,
|
|
||||||
!!ops->recover, bp);
|
|
||||||
#endif
|
|
||||||
if (IS_ERR(reporter)) {
|
|
||||||
netdev_warn(bp->dev, "Failed to create %s health reporter, rc = %ld\n",
|
|
||||||
ops->name, PTR_ERR(reporter));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reporter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bnxt_dl_fw_reporters_create(struct bnxt *bp)
|
void bnxt_dl_fw_reporters_create(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
struct bnxt_fw_health *health = bp->fw_health;
|
struct bnxt_fw_health *health = bp->fw_health;
|
||||||
|
|
@ -359,9 +299,15 @@ void bnxt_dl_fw_reporters_create(struct bnxt *bp)
|
||||||
goto err_recovery;
|
goto err_recovery;
|
||||||
|
|
||||||
health->fw_reset_reporter =
|
health->fw_reset_reporter =
|
||||||
__bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reset_reporter_ops);
|
devlink_health_reporter_create(bp->dl,
|
||||||
if (!health->fw_reset_reporter)
|
&bnxt_dl_fw_reset_reporter_ops,
|
||||||
|
0, true, bp);
|
||||||
|
if (IS_ERR(health->fw_reset_reporter)) {
|
||||||
|
netdev_warn(bp->dev, "Failed to create FW reset health reporter, rc = %ld\n",
|
||||||
|
PTR_ERR(health->fw_reset_reporter));
|
||||||
|
health->fw_reset_reporter = NULL;
|
||||||
bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET;
|
bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
err_recovery:
|
err_recovery:
|
||||||
if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
|
if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
|
||||||
|
|
@ -369,8 +315,13 @@ err_recovery:
|
||||||
|
|
||||||
if (!health->fw_reporter) {
|
if (!health->fw_reporter) {
|
||||||
health->fw_reporter =
|
health->fw_reporter =
|
||||||
__bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reporter_ops);
|
devlink_health_reporter_create(bp->dl,
|
||||||
if (!health->fw_reporter) {
|
&bnxt_dl_fw_reporter_ops,
|
||||||
|
0, false, bp);
|
||||||
|
if (IS_ERR(health->fw_reporter)) {
|
||||||
|
netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n",
|
||||||
|
PTR_ERR(health->fw_reporter));
|
||||||
|
health->fw_reporter = NULL;
|
||||||
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
|
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -380,9 +331,15 @@ err_recovery:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
health->fw_fatal_reporter =
|
health->fw_fatal_reporter =
|
||||||
__bnxt_dl_reporter_create(bp, &bnxt_dl_fw_fatal_reporter_ops);
|
devlink_health_reporter_create(bp->dl,
|
||||||
if (!health->fw_fatal_reporter)
|
&bnxt_dl_fw_fatal_reporter_ops,
|
||||||
|
0, true, bp);
|
||||||
|
if (IS_ERR(health->fw_fatal_reporter)) {
|
||||||
|
netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
|
||||||
|
PTR_ERR(health->fw_fatal_reporter));
|
||||||
|
health->fw_fatal_reporter = NULL;
|
||||||
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
|
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all)
|
void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all)
|
||||||
|
|
@ -560,20 +517,17 @@ static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
|
static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
|
||||||
union devlink_param_value *val)
|
int msg_len, union devlink_param_value *val)
|
||||||
{
|
{
|
||||||
struct hwrm_nvm_get_variable_input *req = msg;
|
struct hwrm_nvm_get_variable_input *req = msg;
|
||||||
struct bnxt_dl_nvm_param nvm_param;
|
struct bnxt_dl_nvm_param nvm_param;
|
||||||
struct hwrm_err_output *resp;
|
|
||||||
union bnxt_nvm_data *data;
|
union bnxt_nvm_data *data;
|
||||||
dma_addr_t data_dma_addr;
|
dma_addr_t data_dma_addr;
|
||||||
int idx = 0, rc, i;
|
int idx = 0, rc, i;
|
||||||
|
|
||||||
/* Get/Set NVM CFG parameter is supported only on PFs */
|
/* Get/Set NVM CFG parameter is supported only on PFs */
|
||||||
if (BNXT_VF(bp)) {
|
if (BNXT_VF(bp))
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
|
for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
|
||||||
if (nvm_params[i].id == param_id) {
|
if (nvm_params[i].id == param_id) {
|
||||||
|
|
@ -582,22 +536,18 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == ARRAY_SIZE(nvm_params)) {
|
if (i == ARRAY_SIZE(nvm_params))
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
|
||||||
|
|
||||||
if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
|
if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
|
||||||
idx = bp->pf.port_id;
|
idx = bp->pf.port_id;
|
||||||
else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
|
else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
|
||||||
idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;
|
idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;
|
||||||
|
|
||||||
data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
|
data = dma_zalloc_coherent(&bp->pdev->dev, sizeof(*data),
|
||||||
|
&data_dma_addr, GFP_KERNEL);
|
||||||
if (!data) {
|
if (!data)
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
req->dest_data_addr = cpu_to_le64(data_dma_addr);
|
req->dest_data_addr = cpu_to_le64(data_dma_addr);
|
||||||
req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
|
req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
|
||||||
|
|
@ -606,24 +556,26 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
|
||||||
if (idx)
|
if (idx)
|
||||||
req->dimensions = cpu_to_le16(1);
|
req->dimensions = cpu_to_le16(1);
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
|
if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
|
||||||
bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
|
bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
|
||||||
nvm_param.dl_num_bytes);
|
nvm_param.dl_num_bytes);
|
||||||
rc = hwrm_req_send(bp, msg);
|
rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
rc = hwrm_req_send_silent(bp, msg);
|
rc = hwrm_send_message_silent(bp, msg, msg_len,
|
||||||
|
HWRM_CMD_TIMEOUT);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
bnxt_copy_from_nvm_data(val, data,
|
bnxt_copy_from_nvm_data(val, data,
|
||||||
nvm_param.nvm_num_bits,
|
nvm_param.nvm_num_bits,
|
||||||
nvm_param.dl_num_bytes);
|
nvm_param.dl_num_bytes);
|
||||||
} else {
|
} else {
|
||||||
|
struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
|
|
||||||
if (resp->cmd_err ==
|
if (resp->cmd_err ==
|
||||||
NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
|
NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr);
|
||||||
if (rc == -EACCES)
|
if (rc == -EACCES)
|
||||||
netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
|
netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -632,35 +584,30 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
|
||||||
static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
|
static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
|
||||||
struct devlink_param_gset_ctx *ctx)
|
struct devlink_param_gset_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct hwrm_nvm_get_variable_input *req;
|
struct hwrm_nvm_get_variable_input req = {0};
|
||||||
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_GET_VARIABLE, -1, -1);
|
||||||
if (rc)
|
rc = bnxt_hwrm_nvm_req(bp, id, &req, sizeof(req), &ctx->val);
|
||||||
return rc;
|
if (!rc)
|
||||||
|
if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
|
||||||
|
ctx->val.vbool = !ctx->val.vbool;
|
||||||
|
|
||||||
rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
|
|
||||||
if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
|
|
||||||
ctx->val.vbool = !ctx->val.vbool;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
|
static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
|
||||||
struct devlink_param_gset_ctx *ctx)
|
struct devlink_param_gset_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
struct hwrm_nvm_set_variable_input req = {0};
|
||||||
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
||||||
struct hwrm_nvm_set_variable_input *req;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
|
if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
|
||||||
ctx->val.vbool = !ctx->val.vbool;
|
ctx->val.vbool = !ctx->val.vbool;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_SET_VARIABLE, -1, -1);
|
||||||
if (rc)
|
return bnxt_hwrm_nvm_req(bp, id, &req, sizeof(req), &ctx->val);
|
||||||
return rc;
|
|
||||||
|
|
||||||
return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IGNORE_ARI
|
#ifdef HAVE_IGNORE_ARI
|
||||||
|
|
@ -728,7 +675,7 @@ static int bnxt_dl_params_register(struct bnxt *bp)
|
||||||
rc = devlink_params_register(bp->dl, bnxt_dl_params,
|
rc = devlink_params_register(bp->dl, bnxt_dl_params,
|
||||||
ARRAY_SIZE(bnxt_dl_params));
|
ARRAY_SIZE(bnxt_dl_params));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n",
|
netdev_warn(bp->dev, "devlink_params_register failed. rc=%d",
|
||||||
rc);
|
rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -736,7 +683,7 @@ static int bnxt_dl_params_register(struct bnxt *bp)
|
||||||
rc = devlink_port_params_register(&bp->dl_port, bnxt_dl_port_params,
|
rc = devlink_port_params_register(&bp->dl_port, bnxt_dl_port_params,
|
||||||
ARRAY_SIZE(bnxt_dl_port_params));
|
ARRAY_SIZE(bnxt_dl_port_params));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netdev_err(bp->dev, "devlink_port_params_register failed\n");
|
netdev_err(bp->dev, "devlink_port_params_register failed");
|
||||||
devlink_params_unregister(bp->dl, bnxt_dl_params,
|
devlink_params_unregister(bp->dl, bnxt_dl_params,
|
||||||
ARRAY_SIZE(bnxt_dl_params));
|
ARRAY_SIZE(bnxt_dl_params));
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -773,7 +720,7 @@ int bnxt_dl_register(struct bnxt *bp)
|
||||||
else
|
else
|
||||||
dl = devlink_alloc(&bnxt_vf_dl_ops, sizeof(struct bnxt_dl));
|
dl = devlink_alloc(&bnxt_vf_dl_ops, sizeof(struct bnxt_dl));
|
||||||
if (!dl) {
|
if (!dl) {
|
||||||
netdev_warn(bp->dev, "devlink_alloc failed\n");
|
netdev_warn(bp->dev, "devlink_alloc failed");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -788,7 +735,7 @@ int bnxt_dl_register(struct bnxt *bp)
|
||||||
|
|
||||||
rc = devlink_register(dl, &bp->pdev->dev);
|
rc = devlink_register(dl, &bp->pdev->dev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc);
|
netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc);
|
||||||
goto err_dl_free;
|
goto err_dl_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -803,7 +750,7 @@ int bnxt_dl_register(struct bnxt *bp)
|
||||||
#endif
|
#endif
|
||||||
rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
|
rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netdev_err(bp->dev, "devlink_port_register failed\n");
|
netdev_err(bp->dev, "devlink_port_register failed");
|
||||||
goto err_dl_unreg;
|
goto err_dl_unreg;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DEVLINK_PORT_PARAM */
|
#endif /* HAVE_DEVLINK_PORT_PARAM */
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl)
|
||||||
#define BNXT_NVM_CFG_VER_BITS 24
|
#define BNXT_NVM_CFG_VER_BITS 24
|
||||||
#define BNXT_NVM_CFG_VER_BYTES 4
|
#define BNXT_NVM_CFG_VER_BYTES 4
|
||||||
|
|
||||||
#define BNXT_MSIX_VEC_MAX 512
|
#define BNXT_MSIX_VEC_MAX 1280
|
||||||
#define BNXT_MSIX_VEC_MIN_MAX 128
|
#define BNXT_MSIX_VEC_MIN_MAX 128
|
||||||
|
|
||||||
union bnxt_nvm_data {
|
union bnxt_nvm_data {
|
||||||
|
|
|
||||||
|
|
@ -36,32 +36,3 @@ void bnxt_dim_work(struct work_struct *work)
|
||||||
bnxt_hwrm_set_ring_coal(bnapi->bp, bnapi);
|
bnxt_hwrm_set_ring_coal(bnapi->bp, bnapi);
|
||||||
dim->state = DIM_START_MEASURE;
|
dim->state = DIM_START_MEASURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_DIM
|
|
||||||
void net_dim(struct dim *dim, struct dim_sample end_sample)
|
|
||||||
{
|
|
||||||
struct dim_stats curr_stats;
|
|
||||||
u16 nevents;
|
|
||||||
|
|
||||||
switch (dim->state) {
|
|
||||||
case DIM_MEASURE_IN_PROGRESS:
|
|
||||||
nevents = BIT_GAP(BITS_PER_TYPE(u16),
|
|
||||||
end_sample.event_ctr,
|
|
||||||
dim->start_sample.event_ctr);
|
|
||||||
if (nevents < DIM_NEVENTS)
|
|
||||||
break;
|
|
||||||
dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats);
|
|
||||||
if (net_dim_decision(&curr_stats, dim)) {
|
|
||||||
dim->state = DIM_APPLY_NEW_PROFILE;
|
|
||||||
schedule_work(&dim->work);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fallthrough;
|
|
||||||
case DIM_START_MEASURE:
|
|
||||||
dim->state = DIM_MEASURE_IN_PROGRESS;
|
|
||||||
break;
|
|
||||||
case DIM_APPLY_NEW_PROFILE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,32 @@ static inline void dim_calc_stats(struct dim_sample *start,
|
||||||
delta_us);
|
delta_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_dim(struct dim *dim, struct dim_sample end_sample);
|
static inline void net_dim(struct dim *dim,
|
||||||
|
struct dim_sample end_sample)
|
||||||
|
{
|
||||||
|
struct dim_stats curr_stats;
|
||||||
|
u16 nevents;
|
||||||
|
|
||||||
|
switch (dim->state) {
|
||||||
|
case DIM_MEASURE_IN_PROGRESS:
|
||||||
|
nevents = BIT_GAP(BITS_PER_TYPE(u16),
|
||||||
|
end_sample.event_ctr,
|
||||||
|
dim->start_sample.event_ctr);
|
||||||
|
if (nevents < DIM_NEVENTS)
|
||||||
|
break;
|
||||||
|
dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats);
|
||||||
|
if (net_dim_decision(&curr_stats, dim)) {
|
||||||
|
dim->state = DIM_APPLY_NEW_PROFILE;
|
||||||
|
schedule_work(&dim->work);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case DIM_START_MEASURE:
|
||||||
|
dim->state = DIM_MEASURE_IN_PROGRESS;
|
||||||
|
break;
|
||||||
|
case DIM_APPLY_NEW_PROFILE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* NET_DIM_H */
|
#endif /* NET_DIM_H */
|
||||||
|
|
|
||||||
|
|
@ -1,497 +0,0 @@
|
||||||
/* Broadcom NetXtreme-C/E network driver.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Broadcom Limited
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
|
|
||||||
#include "bnxt_compat.h"
|
|
||||||
#include "bnxt_hsi.h"
|
|
||||||
#include "bnxt.h"
|
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_eem.h"
|
|
||||||
|
|
||||||
static int bnxt_hwrm_cfa_eem_qcaps(struct bnxt *bp, enum bnxt_eem_dir dir)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_ctx_mem_info *ctxp = &bp->eem_info->eem_ctx_info[dir];
|
|
||||||
struct bnxt_eem_pg_misc *tbl = &ctxp->eem_misc[KEY0_TABLE];
|
|
||||||
struct bnxt_eem_caps *cap = &bp->eem_info->eem_caps[dir];
|
|
||||||
struct hwrm_cfa_eem_qcaps_output *resp;
|
|
||||||
struct hwrm_cfa_eem_qcaps_input *req;
|
|
||||||
u32 flags;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_EEM_QCAPS);
|
|
||||||
if (!rc) {
|
|
||||||
flags = dir == BNXT_EEM_DIR_TX ?
|
|
||||||
CFA_EEM_QCAPS_REQ_FLAGS_PATH_TX :
|
|
||||||
CFA_EEM_QCAPS_REQ_FLAGS_PATH_RX;
|
|
||||||
req->flags = cpu_to_le32(flags);
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
if (rc) {
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
netdev_warn(bp->dev, "Failed to read CFA %s EEM Capabilities\n",
|
|
||||||
BNXT_EEM_DIR(dir));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
cap->flags = le32_to_cpu(resp->flags);
|
|
||||||
cap->supported = le32_to_cpu(resp->supported);
|
|
||||||
cap->max_entries_supported = le32_to_cpu(resp->max_entries_supported);
|
|
||||||
cap->key_entry_size = le16_to_cpu(resp->key_entry_size);
|
|
||||||
cap->record_entry_size = le16_to_cpu(resp->record_entry_size);
|
|
||||||
cap->efc_entry_size = le16_to_cpu(resp->efc_entry_size);
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
|
|
||||||
netdev_dbg(bp->dev, "%s CFA EEM Capabilities:\n", BNXT_EEM_DIR(dir));
|
|
||||||
netdev_dbg(bp->dev, "supported: 0x%x max_entries_supported: 0x%x\n",
|
|
||||||
resp->supported, resp->max_entries_supported);
|
|
||||||
netdev_dbg(bp->dev, "key_entry_size: 0x%x record_entry_size: 0x%x\n",
|
|
||||||
resp->key_entry_size, resp->record_entry_size);
|
|
||||||
|
|
||||||
tbl[KEY0_TABLE].type = KEY0_TABLE;
|
|
||||||
tbl[KEY1_TABLE].type = KEY1_TABLE;
|
|
||||||
tbl[RECORD_TABLE].type = RECORD_TABLE;
|
|
||||||
tbl[EFC_TABLE].type = EFC_TABLE;
|
|
||||||
|
|
||||||
tbl[KEY0_TABLE].entry_size = cap->key_entry_size;
|
|
||||||
tbl[KEY1_TABLE].entry_size = cap->key_entry_size;
|
|
||||||
tbl[RECORD_TABLE].entry_size = cap->record_entry_size;
|
|
||||||
tbl[EFC_TABLE].entry_size = cap->efc_entry_size;
|
|
||||||
|
|
||||||
if (BNXT_CHIP_P4(bp) && (dir == BNXT_EEM_DIR_TX))
|
|
||||||
cap->record_entry_size = BNXT_EEM_TX_RECORD_SIZE;
|
|
||||||
|
|
||||||
tbl[KEY0_TABLE].ctx_id = BNXT_EEM_CTX_ID_INVALID;
|
|
||||||
tbl[KEY1_TABLE].ctx_id = BNXT_EEM_CTX_ID_INVALID;
|
|
||||||
tbl[RECORD_TABLE].ctx_id = BNXT_EEM_CTX_ID_INVALID;
|
|
||||||
tbl[EFC_TABLE].ctx_id = BNXT_EEM_CTX_ID_INVALID;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bnxt_hwrm_query_eem_caps(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
if (!(bp->fw_cap & BNXT_FW_CAP_CFA_EEM))
|
|
||||||
return;
|
|
||||||
|
|
||||||
bp->eem_info = kzalloc(sizeof(*bp->eem_info), GFP_KERNEL);
|
|
||||||
if (!bp->eem_info)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Query tx eem caps */
|
|
||||||
bnxt_hwrm_cfa_eem_qcaps(bp, BNXT_EEM_DIR_TX);
|
|
||||||
|
|
||||||
/* Query rx eem caps */
|
|
||||||
bnxt_hwrm_cfa_eem_qcaps(bp, BNXT_EEM_DIR_RX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_hwrm_cfa_eem_op(struct bnxt *bp, enum bnxt_eem_dir dir, u16 op)
|
|
||||||
{
|
|
||||||
struct hwrm_cfa_eem_op_input *req;
|
|
||||||
u32 flags;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (op != CFA_EEM_OP_REQ_OP_EEM_ENABLE &&
|
|
||||||
op != CFA_EEM_OP_REQ_OP_EEM_DISABLE &&
|
|
||||||
op != CFA_EEM_OP_REQ_OP_EEM_CLEANUP)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_EEM_OP);
|
|
||||||
if (!rc) {
|
|
||||||
flags = (dir == BNXT_EEM_DIR_TX) ?
|
|
||||||
CFA_EEM_OP_REQ_FLAGS_PATH_TX :
|
|
||||||
CFA_EEM_OP_REQ_FLAGS_PATH_RX;
|
|
||||||
req->flags = cpu_to_le32(flags);
|
|
||||||
req->op = cpu_to_le16(op);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
netdev_warn(bp->dev, "%s CFA EEM OP:%d failed, rc=%d",
|
|
||||||
BNXT_EEM_DIR(dir), op, rc);
|
|
||||||
else
|
|
||||||
netdev_dbg(bp->dev, "%s CFA EEM OP:%d succeeded",
|
|
||||||
BNXT_EEM_DIR(dir), op);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_hwrm_cfa_eem_mem_unrgtr(struct bnxt *bp, u16 *ctx_id)
|
|
||||||
{
|
|
||||||
struct hwrm_cfa_ctx_mem_unrgtr_input *req;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (*ctx_id == BNXT_EEM_CTX_ID_INVALID)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_CTX_MEM_UNRGTR);
|
|
||||||
if (!rc) {
|
|
||||||
req->ctx_id = cpu_to_le16(*ctx_id);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
netdev_warn(bp->dev, "Failed to Unregister CFA EEM Mem\n");
|
|
||||||
else
|
|
||||||
*ctx_id = BNXT_EEM_CTX_ID_INVALID;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_eem_ctx_unreg(struct bnxt *bp, enum bnxt_eem_dir dir)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_ctx_mem_info *ctxp = &bp->eem_info->eem_ctx_info[dir];
|
|
||||||
struct bnxt_eem_pg_misc *tbl_misc;
|
|
||||||
struct bnxt_ctx_pg_info *tbl;
|
|
||||||
int tbl_type;
|
|
||||||
|
|
||||||
for (tbl_type = KEY0_TABLE; tbl_type < MAX_TABLE; tbl_type++) {
|
|
||||||
if (tbl_type == EFC_TABLE)
|
|
||||||
continue;
|
|
||||||
tbl = &ctxp->eem_tables[tbl_type];
|
|
||||||
tbl_misc = &ctxp->eem_misc[tbl_type];
|
|
||||||
bnxt_hwrm_cfa_eem_mem_unrgtr(bp, &tbl_misc->ctx_id);
|
|
||||||
bnxt_free_ctx_pg_tbls(bp, tbl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_unconfig_eem(struct bnxt *bp, enum bnxt_eem_dir dir)
|
|
||||||
{
|
|
||||||
bool configured = false;
|
|
||||||
|
|
||||||
if (!(bp->fw_cap & BNXT_FW_CAP_CFA_EEM) ||
|
|
||||||
dir < BNXT_EEM_DIR_TX || dir > BNXT_EEM_DIR_RX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dir == BNXT_EEM_DIR_TX) {
|
|
||||||
configured = bp->eem_info->eem_cfg_tx_dir ? true : false;
|
|
||||||
bp->eem_info->eem_cfg_tx_dir = false;
|
|
||||||
} else {
|
|
||||||
configured = bp->eem_info->eem_cfg_rx_dir ? true : false;
|
|
||||||
bp->eem_info->eem_cfg_rx_dir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configured) {
|
|
||||||
bnxt_hwrm_cfa_eem_op(bp, dir, CFA_EEM_OP_REQ_OP_EEM_DISABLE);
|
|
||||||
bnxt_hwrm_cfa_eem_op(bp, dir, CFA_EEM_OP_REQ_OP_EEM_CLEANUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bp->eem_info->eem_primary)
|
|
||||||
bnxt_eem_ctx_unreg(bp, dir);
|
|
||||||
|
|
||||||
if (!bp->eem_info->eem_cfg_tx_dir && !bp->eem_info->eem_cfg_rx_dir) {
|
|
||||||
bp->eem_info->eem_primary = false;
|
|
||||||
bp->eem_info->eem_group = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_validate_num_entries(struct bnxt *bp,
|
|
||||||
enum bnxt_eem_dir dir,
|
|
||||||
u32 num_entries)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_caps *cap = &bp->eem_info->eem_caps[dir];
|
|
||||||
|
|
||||||
if (num_entries < BNXT_EEM_MIN_ENTRIES ||
|
|
||||||
num_entries > cap->max_entries_supported ||
|
|
||||||
num_entries != roundup_pow_of_two(num_entries)) {
|
|
||||||
netdev_warn(bp->dev, "EEM: Invalid num_entries requested: %u\n",
|
|
||||||
num_entries);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bp->eem_info->eem_ctx_info[dir].num_entries = num_entries;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_eem_pg_size_table(struct bnxt_eem_caps *cap, int tbl_type,
|
|
||||||
u32 num_entries, u32 *size, u8 *depth,
|
|
||||||
struct bnxt_eem_pg_misc *tbl_misc)
|
|
||||||
{
|
|
||||||
u32 mem_size = 0;
|
|
||||||
|
|
||||||
if (tbl_type == KEY0_TABLE || tbl_type == KEY1_TABLE) {
|
|
||||||
mem_size = cap->key_entry_size * num_entries;
|
|
||||||
tbl_misc->entry_size = cap->key_entry_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tbl_type == RECORD_TABLE) {
|
|
||||||
mem_size = cap->record_entry_size * num_entries * 2;
|
|
||||||
tbl_misc->entry_size = cap->record_entry_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tbl_type == EFC_TABLE) {
|
|
||||||
mem_size = cap->efc_entry_size * num_entries;
|
|
||||||
tbl_misc->entry_size = cap->efc_entry_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbl_misc->type = tbl_type;
|
|
||||||
*size = mem_size;
|
|
||||||
*depth = (DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE) < MAX_CTX_PAGES) ?
|
|
||||||
1 : 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 bnxt_eem_page_level_code(int pg_lvl)
|
|
||||||
{
|
|
||||||
u8 page_level;
|
|
||||||
|
|
||||||
switch (pg_lvl) {
|
|
||||||
case PT_LVL_2:
|
|
||||||
page_level = CFA_CTX_MEM_RGTR_REQ_PAGE_LEVEL_LVL_2;
|
|
||||||
break;
|
|
||||||
case PT_LVL_1:
|
|
||||||
page_level = CFA_CTX_MEM_RGTR_REQ_PAGE_LEVEL_LVL_1;
|
|
||||||
break;
|
|
||||||
case PT_LVL_0:
|
|
||||||
page_level = CFA_CTX_MEM_RGTR_REQ_PAGE_LEVEL_LVL_0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
page_level = 0xff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return page_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u8 bnxt_eem_page_size_code(u32 page_size)
|
|
||||||
{
|
|
||||||
u8 pg_sz_code = 0xff;
|
|
||||||
|
|
||||||
switch (page_size) {
|
|
||||||
case BNXT_EEM_PG_SZ_4K:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_4K;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_8K:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_8K;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_64K:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_64K;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_256K:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_256K;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_1M:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_1M;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_2M:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_2M;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_4M:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_4M;
|
|
||||||
break;
|
|
||||||
case BNXT_EEM_PG_SZ_1G:
|
|
||||||
pg_sz_code = CFA_CTX_MEM_RGTR_REQ_PAGE_SIZE_1G;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pg_sz_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_hwrm_cfa_eem_mem_rgtr(struct bnxt *bp, int page_level,
|
|
||||||
u32 page_size, u64 page_dir, u16 *ctx_id)
|
|
||||||
{
|
|
||||||
struct hwrm_cfa_ctx_mem_rgtr_output *resp;
|
|
||||||
struct hwrm_cfa_ctx_mem_rgtr_input *req;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_CTX_MEM_RGTR);
|
|
||||||
if (!rc) {
|
|
||||||
req->flags = 0;
|
|
||||||
req->page_level = bnxt_eem_page_level_code(page_level);
|
|
||||||
req->page_size = bnxt_eem_page_size_code(page_size);
|
|
||||||
req->page_dir = cpu_to_le64(page_dir);
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
if (rc) {
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
netdev_warn(bp->dev, "Failed to register CFA EEM Mem\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ctx_id = le16_to_cpu(resp->ctx_id);
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_ctx_reg(struct bnxt *bp, enum bnxt_eem_dir dir,
|
|
||||||
u16 grp_id, u32 num_entries)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_ctx_mem_info *ctxp = &bp->eem_info->eem_ctx_info[dir];
|
|
||||||
struct bnxt_eem_caps *cap = &bp->eem_info->eem_caps[dir];
|
|
||||||
struct bnxt_eem_pg_misc *tbl_misc;
|
|
||||||
struct bnxt_ctx_pg_info *tbl;
|
|
||||||
int tbl_type;
|
|
||||||
u32 mem_size;
|
|
||||||
u8 depth;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
ctxp->num_entries = num_entries;
|
|
||||||
if (!num_entries)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (tbl_type = KEY0_TABLE; tbl_type < MAX_TABLE; tbl_type++) {
|
|
||||||
tbl = &ctxp->eem_tables[tbl_type];
|
|
||||||
tbl_misc = &ctxp->eem_misc[tbl_type];
|
|
||||||
|
|
||||||
/* No EFC table support, skip EFC */
|
|
||||||
if (tbl_type == EFC_TABLE) {
|
|
||||||
tbl_misc->ctx_id = 0;
|
|
||||||
tbl_misc->entry_size = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bnxt_eem_pg_size_table(cap, tbl_type, num_entries,
|
|
||||||
&mem_size, &depth, tbl_misc);
|
|
||||||
rc = bnxt_alloc_ctx_pg_tbls(bp, tbl, mem_size, depth, false);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev,
|
|
||||||
"alloc failed size 0x%x, depth %d\n",
|
|
||||||
mem_size, depth);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_cfa_eem_mem_rgtr(bp, depth,
|
|
||||||
BNXT_EEM_PAGE_SIZE,
|
|
||||||
tbl->ring_mem.pg_tbl_map,
|
|
||||||
&tbl_misc->ctx_id);
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
cleanup:
|
|
||||||
bnxt_eem_ctx_unreg(bp, dir);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_hwrm_cfa_eem_cfg(struct bnxt *bp, enum bnxt_eem_dir dir,
|
|
||||||
u32 cfg_flags,
|
|
||||||
u16 grp_id)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_ctx_mem_info *ctxp = &bp->eem_info->eem_ctx_info[dir];
|
|
||||||
struct bnxt_eem_pg_misc *tbl = &ctxp->eem_misc[KEY0_TABLE];
|
|
||||||
struct hwrm_cfa_eem_cfg_input *req;
|
|
||||||
u32 flags;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_EEM_CFG);
|
|
||||||
if (!rc) {
|
|
||||||
flags = (dir == BNXT_EEM_DIR_TX) ?
|
|
||||||
CFA_EEM_CFG_REQ_FLAGS_PATH_TX :
|
|
||||||
CFA_EEM_CFG_REQ_FLAGS_PATH_RX;
|
|
||||||
flags |= CFA_EEM_CFG_REQ_FLAGS_PREFERRED_OFFLOAD;
|
|
||||||
|
|
||||||
if (cfg_flags) {
|
|
||||||
req->key0_ctx_id = cpu_to_le16(tbl[KEY0_TABLE].ctx_id);
|
|
||||||
req->key1_ctx_id = cpu_to_le16(tbl[KEY1_TABLE].ctx_id);
|
|
||||||
req->record_ctx_id = cpu_to_le16(tbl[RECORD_TABLE].ctx_id);
|
|
||||||
req->efc_ctx_id = cpu_to_le16(tbl[EFC_TABLE].ctx_id);
|
|
||||||
req->num_entries = cpu_to_le32(ctxp->num_entries);
|
|
||||||
} else {
|
|
||||||
flags |= CFA_EEM_CFG_REQ_FLAGS_SECONDARY_PF;
|
|
||||||
}
|
|
||||||
req->flags = cpu_to_le32(flags);
|
|
||||||
req->group_id = cpu_to_le16(grp_id);
|
|
||||||
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
if (rc) {
|
|
||||||
netdev_warn(bp->dev, "Failed to configure %s CFA EEM: rc=%d",
|
|
||||||
BNXT_EEM_DIR(dir), rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
netdev_dbg(bp->dev, "Configured %s EEM\n", BNXT_EEM_DIR(dir));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_config_eem(struct bnxt *bp, enum bnxt_eem_dir dir, u32 flags,
|
|
||||||
u32 num_entries, u16 grp_id)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!(bp->fw_cap & BNXT_FW_CAP_CFA_EEM) || dir < BNXT_EEM_DIR_TX ||
|
|
||||||
dir > BNXT_EEM_DIR_RX ||
|
|
||||||
bnxt_eem_validate_num_entries(bp, dir, num_entries))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if ((bp->eem_info->eem_cfg_tx_dir && (dir == BNXT_EEM_DIR_TX)) ||
|
|
||||||
(bp->eem_info->eem_cfg_rx_dir && (dir == BNXT_EEM_DIR_RX))) {
|
|
||||||
netdev_warn(bp->dev,
|
|
||||||
"already config the EEM in dir %d\n",
|
|
||||||
dir);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bp->eem_info->eem_primary = flags ? true : false;
|
|
||||||
if (bp->eem_info->eem_primary) {
|
|
||||||
rc = bnxt_eem_ctx_reg(bp, dir, grp_id, num_entries);
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_cfa_eem_cfg(bp, dir, flags, grp_id);
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_cfa_eem_op(bp, dir, CFA_EEM_OP_REQ_OP_EEM_ENABLE);
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (dir == BNXT_EEM_DIR_TX)
|
|
||||||
bp->eem_info->eem_cfg_tx_dir = true;
|
|
||||||
else
|
|
||||||
bp->eem_info->eem_cfg_rx_dir = true;
|
|
||||||
bp->eem_info->eem_group = grp_id;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
cleanup:
|
|
||||||
bnxt_unconfig_eem(bp, dir);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_eem_clear_cfg_system_memory(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
int dir;
|
|
||||||
|
|
||||||
netdev_dbg(bp->dev, "call undo system memory\n");
|
|
||||||
for (dir = BNXT_EEM_DIR_TX; dir < BNXT_EEM_NUM_DIR; dir++)
|
|
||||||
bnxt_unconfig_eem(bp, dir);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_eem_cfg_system_memory(struct bnxt *bp, u32 entry_num)
|
|
||||||
{
|
|
||||||
int dir;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
netdev_dbg(bp->dev,
|
|
||||||
"call cfg system memory, entry num: %d\n",
|
|
||||||
entry_num);
|
|
||||||
|
|
||||||
for (dir = BNXT_EEM_DIR_TX; dir < BNXT_EEM_NUM_DIR; dir++) {
|
|
||||||
rc = bnxt_config_eem(bp, dir, true, entry_num, 0);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev,
|
|
||||||
"config EEM fail. dir %d entry_num %d\n",
|
|
||||||
dir, entry_num);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
cleanup:
|
|
||||||
for (dir = BNXT_EEM_DIR_TX; dir < BNXT_EEM_NUM_DIR; dir++)
|
|
||||||
bnxt_unconfig_eem(bp, dir);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
/* Broadcom NetXtreme-C/E network driver.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Broadcom Limited
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BNXT_EEM_H
|
|
||||||
#define BNXT_EEM_H
|
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
|
|
||||||
#if (PAGE_SHIFT < 12) /* < 4K >> 4K */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 12
|
|
||||||
#elif (PAGE_SHIFT <= 13) /* 4K, 8K */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT PAGE_SHIFT
|
|
||||||
#elif (PAGE_SHIFT < 16) /* 16K, 32K >> 8K */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 13
|
|
||||||
#elif (PAGE_SHIFT <= 17) /* 64K, 128K >> 64K */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 16
|
|
||||||
#elif (PAGE_SHIFT <= 19) /* 256K, 512K >> 256K */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 18
|
|
||||||
#elif (PAGE_SHIFT <= 22) /* 1M, 2M, 4M */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT PAGE_SHIFT
|
|
||||||
#elif (PAGE_SHIFT <= 29) /* 8M ... 512M >> 4M */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 22
|
|
||||||
#else /* >= 1G >> 1G */
|
|
||||||
#define BNXT_EEM_PAGE_SHIFT 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BNXT_EEM_PAGE_SIZE BIT(BNXT_EEM_PAGE_SHIFT)
|
|
||||||
|
|
||||||
#define BNXT_EEM_PG_SZ_4K BIT(12)
|
|
||||||
#define BNXT_EEM_PG_SZ_8K BIT(13)
|
|
||||||
#define BNXT_EEM_PG_SZ_64K BIT(16)
|
|
||||||
#define BNXT_EEM_PG_SZ_256K BIT(18)
|
|
||||||
#define BNXT_EEM_PG_SZ_1M BIT(20)
|
|
||||||
#define BNXT_EEM_PG_SZ_2M BIT(21)
|
|
||||||
#define BNXT_EEM_PG_SZ_4M BIT(22)
|
|
||||||
#define BNXT_EEM_PG_SZ_1G BIT(30)
|
|
||||||
|
|
||||||
#define BNXT_EEM_MIN_ENTRIES BIT(15) /* 32K */
|
|
||||||
#define BNXT_EEM_MAX_ENTRIES BIT(27) /* 128M */
|
|
||||||
|
|
||||||
#define BNXT_EEM_TX_RECORD_SIZE 64
|
|
||||||
#define BNXT_EEM_CTX_ID_INVALID 0xFFFF
|
|
||||||
|
|
||||||
enum bnxt_eem_dir {
|
|
||||||
BNXT_EEM_DIR_TX,
|
|
||||||
BNXT_EEM_DIR_RX,
|
|
||||||
BNXT_EEM_NUM_DIR
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BNXT_EEM_DIR(dir) ((dir) == BNXT_EEM_DIR_TX ? "TX" : "RX")
|
|
||||||
|
|
||||||
enum bnxt_eem_table_type {
|
|
||||||
KEY0_TABLE,
|
|
||||||
KEY1_TABLE,
|
|
||||||
RECORD_TABLE,
|
|
||||||
EFC_TABLE,
|
|
||||||
MAX_TABLE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bnxt_pg_tbl_lvl {
|
|
||||||
PT_LVL_0,
|
|
||||||
PT_LVL_1,
|
|
||||||
PT_LVL_2,
|
|
||||||
PT_LVL_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
/* CFA EEM Caps saved from the response to HWRM_CFA_EEM_QCAPS */
|
|
||||||
struct bnxt_eem_caps {
|
|
||||||
u32 flags;
|
|
||||||
u32 supported;
|
|
||||||
u32 max_entries_supported;
|
|
||||||
u16 key_entry_size;
|
|
||||||
u16 record_entry_size;
|
|
||||||
u16 efc_entry_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_eem_pg_misc {
|
|
||||||
int type;
|
|
||||||
u16 ctx_id;
|
|
||||||
u32 entry_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_eem_ctx_mem_info {
|
|
||||||
u32 num_entries;
|
|
||||||
struct bnxt_eem_pg_misc eem_misc[MAX_TABLE];
|
|
||||||
struct bnxt_ctx_pg_info eem_tables[MAX_TABLE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_eem_info {
|
|
||||||
u8 eem_cfg_tx_dir:1;
|
|
||||||
u8 eem_cfg_rx_dir:1;
|
|
||||||
u8 eem_primary:1;
|
|
||||||
u16 eem_group;
|
|
||||||
struct bnxt_eem_caps eem_caps[BNXT_EEM_NUM_DIR];
|
|
||||||
struct bnxt_eem_ctx_mem_info
|
|
||||||
eem_ctx_info[BNXT_EEM_NUM_DIR];
|
|
||||||
};
|
|
||||||
|
|
||||||
void bnxt_hwrm_query_eem_caps(struct bnxt *bp);
|
|
||||||
int bnxt_eem_clear_cfg_system_memory(struct bnxt *bp);
|
|
||||||
int bnxt_eem_cfg_system_memory(struct bnxt *bp, u32 entry_num);
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -92,13 +92,8 @@ struct hwrm_dbg_cmn_output {
|
||||||
#define BNXT_LED_DFLT_ENABLES(x) \
|
#define BNXT_LED_DFLT_ENABLES(x) \
|
||||||
cpu_to_le32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
|
cpu_to_le32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
|
||||||
|
|
||||||
#define BNXT_FW_RESET_CRASHDUMP (ETH_RESET_CRASHDUMP << ETH_RESET_SHARED_SHIFT)
|
#define BNXT_FW_RESET_AP 0xfffe
|
||||||
#define BNXT_FW_RESET_AP (ETH_RESET_AP << ETH_RESET_SHARED_SHIFT)
|
#define BNXT_FW_RESET_CHIP 0xffff
|
||||||
#define BNXT_FW_RESET_CHIP ((ETH_RESET_MGMT | ETH_RESET_IRQ | \
|
|
||||||
ETH_RESET_DMA | ETH_RESET_FILTER | \
|
|
||||||
ETH_RESET_OFFLOAD | ETH_RESET_MAC | \
|
|
||||||
ETH_RESET_PHY | ETH_RESET_RAM) \
|
|
||||||
<< ETH_RESET_SHARED_SHIFT)
|
|
||||||
|
|
||||||
#define BNXT_PXP_REG_LEN 0x3110
|
#define BNXT_PXP_REG_LEN 0x3110
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
#ifndef BNXT_EXTRA_VER_H
|
#ifndef BNXT_EXTRA_VER_H
|
||||||
#define BNXT_EXTRA_VER_H
|
#define BNXT_EXTRA_VER_H
|
||||||
|
|
||||||
#define DRV_MODULE_EXTRA_VER "-216.1.192.4"
|
#define DRV_MODULE_EXTRA_VER "-216.1.92.0"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,566 +0,0 @@
|
||||||
/* Broadcom NetXtreme-C/E network driver.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Broadcom Limited
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <asm/byteorder.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <linux/dmapool.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/if_ether.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
|
|
||||||
#include "bnxt_compat.h"
|
|
||||||
#include "bnxt_hsi.h"
|
|
||||||
#include "bnxt.h"
|
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
|
|
||||||
static u64 hwrm_calc_sentinel(struct bnxt_hwrm_ctx *ctx, u16 req_type)
|
|
||||||
{
|
|
||||||
return (((u64)ctx) + req_type) ^ BNXT_HWRM_SENTINEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __hwrm_req_init(struct bnxt *bp, void **req, u16 req_type, u32 req_len)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx;
|
|
||||||
dma_addr_t dma_handle;
|
|
||||||
u8 *req_addr;
|
|
||||||
|
|
||||||
if (req_len > BNXT_HWRM_CTX_OFFSET)
|
|
||||||
return -E2BIG;
|
|
||||||
|
|
||||||
req_addr = dma_pool_alloc(bp->hwrm_dma_pool, GFP_KERNEL | __GFP_ZERO,
|
|
||||||
&dma_handle);
|
|
||||||
if (!req_addr)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ctx = (struct bnxt_hwrm_ctx *)(req_addr + BNXT_HWRM_CTX_OFFSET);
|
|
||||||
/* safety first, sentinel used to check for invalid requests */
|
|
||||||
ctx->sentinel = hwrm_calc_sentinel(ctx, req_type);
|
|
||||||
ctx->req_len = req_len;
|
|
||||||
ctx->req = (struct input *)req_addr;
|
|
||||||
ctx->resp = (struct output *)(req_addr + BNXT_HWRM_RESP_OFFSET);
|
|
||||||
ctx->dma_handle = dma_handle;
|
|
||||||
ctx->flags = 0; /* __GFP_ZERO, but be explicit regarding ownership */
|
|
||||||
ctx->timeout = bp->hwrm_cmd_timeout ?: DFLT_HWRM_CMD_TIMEOUT;
|
|
||||||
ctx->allocated = BNXT_HWRM_DMA_SIZE - BNXT_HWRM_CTX_OFFSET;
|
|
||||||
ctx->gfp = GFP_KERNEL;
|
|
||||||
ctx->slice_addr = NULL;
|
|
||||||
|
|
||||||
/* initialize common request fields */
|
|
||||||
ctx->req->req_type = cpu_to_le16(req_type);
|
|
||||||
ctx->req->resp_addr = cpu_to_le64(dma_handle + BNXT_HWRM_RESP_OFFSET);
|
|
||||||
ctx->req->cmpl_ring = cpu_to_le16(BNXT_HWRM_NO_CMPL_RING);
|
|
||||||
ctx->req->target_id = cpu_to_le16(BNXT_HWRM_TARGET);
|
|
||||||
*req = ctx->req;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct bnxt_hwrm_ctx *__hwrm_ctx(struct bnxt *bp, u8 *req_addr)
|
|
||||||
{
|
|
||||||
void *ctx_addr = req_addr + BNXT_HWRM_CTX_OFFSET;
|
|
||||||
struct input *req = (struct input *)req_addr;
|
|
||||||
struct bnxt_hwrm_ctx *ctx = ctx_addr;
|
|
||||||
u64 sentinel;
|
|
||||||
|
|
||||||
if (!req) {
|
|
||||||
/* can only be due to software bug, be loud */
|
|
||||||
netdev_err(bp->dev, "null HWRM request");
|
|
||||||
dump_stack();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HWRM API has no type safety, verify sentinel to validate address */
|
|
||||||
sentinel = hwrm_calc_sentinel(ctx, le16_to_cpu(req->req_type));
|
|
||||||
if (ctx->sentinel != sentinel) {
|
|
||||||
/* can only be due to software bug, be loud */
|
|
||||||
netdev_err(bp->dev, "HWRM sentinel mismatch, req_type = %u\n",
|
|
||||||
(u32)le16_to_cpu(req->req_type));
|
|
||||||
dump_stack();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hwrm_req_silence(struct bnxt *bp, void *req)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
ctx->flags |= BNXT_HWRM_CTX_SILENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hwrm_req_timeout(struct bnxt *bp, void *req, int timeout)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
ctx->timeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hwrm_req_alloc_flags(struct bnxt *bp, void *req, gfp_t gfp)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
ctx->gfp = gfp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hwrm_req_replace(struct bnxt *bp, void *req, void *new_req, u32 len)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
struct input *internal_req = req;
|
|
||||||
u16 req_type;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (len > BNXT_HWRM_CTX_OFFSET)
|
|
||||||
return -E2BIG;
|
|
||||||
|
|
||||||
/* free any existing slices */
|
|
||||||
ctx->allocated = BNXT_HWRM_DMA_SIZE - BNXT_HWRM_CTX_OFFSET;
|
|
||||||
if (ctx->slice_addr) {
|
|
||||||
dma_free_coherent(&bp->pdev->dev, ctx->slice_size,
|
|
||||||
ctx->slice_addr, ctx->slice_handle);
|
|
||||||
ctx->slice_addr = NULL;
|
|
||||||
}
|
|
||||||
ctx->gfp = GFP_KERNEL;
|
|
||||||
|
|
||||||
if ((bp->fw_cap & BNXT_FW_CAP_SHORT_CMD) || len > BNXT_HWRM_MAX_REQ_LEN) {
|
|
||||||
memcpy(internal_req, new_req, len);
|
|
||||||
} else {
|
|
||||||
internal_req->req_type = ((struct input *)new_req)->req_type;
|
|
||||||
ctx->req = new_req;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->req_len = len;
|
|
||||||
ctx->req->resp_addr = cpu_to_le64(ctx->dma_handle +
|
|
||||||
BNXT_HWRM_RESP_OFFSET);
|
|
||||||
|
|
||||||
/* update sentinel for potentially new request type */
|
|
||||||
req_type = le16_to_cpu(internal_req->req_type);
|
|
||||||
ctx->sentinel = hwrm_calc_sentinel(ctx, req_type);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hwrm_req_capture_ts(struct bnxt *bp, void *req,
|
|
||||||
struct ptp_system_timestamp *sts)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
ctx->sts = sts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *hwrm_req_hold(struct bnxt *bp, void *req)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
struct input *input = (struct input *)req;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (ctx->flags & BNXT_HWRM_CTX_OWNED) {
|
|
||||||
/* can only be due to software bug, be loud */
|
|
||||||
netdev_err(bp->dev, "HWRM context already owned, req_type = %u\n",
|
|
||||||
(u32)le16_to_cpu(input->req_type));
|
|
||||||
dump_stack();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->flags |= BNXT_HWRM_CTX_OWNED;
|
|
||||||
return ((u8 *)req) + BNXT_HWRM_RESP_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __hwrm_ctx_drop(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
|
|
||||||
{
|
|
||||||
void *addr = ((u8 *)ctx) - BNXT_HWRM_CTX_OFFSET;
|
|
||||||
dma_addr_t dma_handle = ctx->dma_handle; /* save before invalidate */
|
|
||||||
|
|
||||||
/* unmap any auxiliary DMA slice */
|
|
||||||
if (ctx->slice_addr)
|
|
||||||
dma_free_coherent(&bp->pdev->dev, ctx->slice_size,
|
|
||||||
ctx->slice_addr, ctx->slice_handle);
|
|
||||||
|
|
||||||
/* invalidate, ensure ownership, sentinel and dma_handle are cleared */
|
|
||||||
memset(ctx, 0, sizeof(struct bnxt_hwrm_ctx));
|
|
||||||
|
|
||||||
/* return the buffer to the DMA pool */
|
|
||||||
if (dma_handle)
|
|
||||||
dma_pool_free(bp->hwrm_dma_pool, addr, dma_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void because failure is irrecoverable */
|
|
||||||
void hwrm_req_drop(struct bnxt *bp, void *req)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (ctx)
|
|
||||||
__hwrm_ctx_drop(bp, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __hwrm_to_stderr(u32 hwrm_err)
|
|
||||||
{
|
|
||||||
switch (hwrm_err) {
|
|
||||||
case HWRM_ERR_CODE_SUCCESS:
|
|
||||||
return 0;
|
|
||||||
case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED:
|
|
||||||
return -EACCES;
|
|
||||||
case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR:
|
|
||||||
return -ENOSPC;
|
|
||||||
case HWRM_ERR_CODE_INVALID_PARAMS:
|
|
||||||
case HWRM_ERR_CODE_INVALID_FLAGS:
|
|
||||||
case HWRM_ERR_CODE_INVALID_ENABLES:
|
|
||||||
case HWRM_ERR_CODE_UNSUPPORTED_TLV:
|
|
||||||
case HWRM_ERR_CODE_UNSUPPORTED_OPTION_ERR:
|
|
||||||
return -EINVAL;
|
|
||||||
case HWRM_ERR_CODE_NO_BUFFER:
|
|
||||||
return -ENOMEM;
|
|
||||||
case HWRM_ERR_CODE_HOT_RESET_PROGRESS:
|
|
||||||
case HWRM_ERR_CODE_BUSY:
|
|
||||||
return -EAGAIN;
|
|
||||||
case HWRM_ERR_CODE_CMD_NOT_SUPPORTED:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
default:
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct bnxt_hwrm_wait_token *
|
|
||||||
__hwrm_acquire_token(struct bnxt *bp, enum bnxt_hwrm_chnl dst)
|
|
||||||
__acquires(&bp->hwrm_cmd_lock)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_wait_token *token;
|
|
||||||
|
|
||||||
token = kzalloc(sizeof(*token), GFP_KERNEL);
|
|
||||||
if (!token)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mutex_lock(&bp->hwrm_cmd_lock);
|
|
||||||
|
|
||||||
token->dst = dst;
|
|
||||||
token->state = BNXT_HWRM_PENDING;
|
|
||||||
if (dst == BNXT_HWRM_CHNL_CHIMP) {
|
|
||||||
token->seq_id = bp->hwrm_cmd_seq++;
|
|
||||||
hlist_add_head_rcu(&token->node, &bp->hwrm_pending_list);
|
|
||||||
} else {
|
|
||||||
token->seq_id = bp->hwrm_cmd_kong_seq++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
__hwrm_release_token(struct bnxt *bp, struct bnxt_hwrm_wait_token *token)
|
|
||||||
__releases(&bp->hwrm_cmd_lock)
|
|
||||||
{
|
|
||||||
if (token->dst == BNXT_HWRM_CHNL_CHIMP) {
|
|
||||||
hlist_del_rcu(&token->node);
|
|
||||||
kfree_rcu(token, rcu);
|
|
||||||
} else {
|
|
||||||
kfree(token);
|
|
||||||
}
|
|
||||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hwrm_update_token(struct bnxt *bp, u16 seq_id, enum bnxt_hwrm_wait_state state)
|
|
||||||
{
|
|
||||||
struct hlist_node __maybe_unused *dummy;
|
|
||||||
struct bnxt_hwrm_wait_token *token;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
__hlist_for_each_entry_rcu(token, dummy, &bp->hwrm_pending_list, node) {
|
|
||||||
if (token->seq_id == seq_id) {
|
|
||||||
WRITE_ONCE(token->state, state);
|
|
||||||
rcu_read_unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
netdev_err(bp->dev, "Invalid hwrm seq id %d\n", seq_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
|
|
||||||
{
|
|
||||||
u32 doorbell_offset = BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER;
|
|
||||||
enum bnxt_hwrm_chnl dst = BNXT_HWRM_CHNL_CHIMP;
|
|
||||||
u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
|
|
||||||
struct bnxt_hwrm_wait_token *token = NULL;
|
|
||||||
struct hwrm_short_input short_input = {0};
|
|
||||||
u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;
|
|
||||||
int i, timeout, tmo_count, rc = -EBUSY;
|
|
||||||
u32 *data = (u32 *)ctx->req;
|
|
||||||
u32 msg_len = ctx->req_len;
|
|
||||||
u16 len = 0;
|
|
||||||
u8 *valid;
|
|
||||||
|
|
||||||
#ifndef HSI_DBG_DISABLE
|
|
||||||
decode_hwrm_req(ctx->req);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (msg_len > BNXT_HWRM_MAX_REQ_LEN &&
|
|
||||||
msg_len > bp->hwrm_max_ext_req_len) {
|
|
||||||
rc = -E2BIG;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hwrm_req_kong(bp, ctx->req)) {
|
|
||||||
dst = BNXT_HWRM_CHNL_KONG;
|
|
||||||
bar_offset = BNXT_GRCPF_REG_KONG_COMM;
|
|
||||||
doorbell_offset = BNXT_GRCPF_REG_KONG_COMM_TRIGGER;
|
|
||||||
if (le16_to_cpu(ctx->req->cmpl_ring) != INVALID_HW_RING_ID) {
|
|
||||||
netdev_err(bp->dev, "Ring completions not supported for KONG commands, req_type = %d\n",
|
|
||||||
(u32)le16_to_cpu(ctx->req->req_type));
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->flags & BNXT_HWRM_RESP_DIRTY)
|
|
||||||
memset(ctx->resp, 0, PAGE_SIZE);
|
|
||||||
|
|
||||||
token = __hwrm_acquire_token(bp, dst);
|
|
||||||
if (!token) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
ctx->req->seq_id = cpu_to_le16(token->seq_id);
|
|
||||||
|
|
||||||
if ((bp->fw_cap & BNXT_FW_CAP_SHORT_CMD) ||
|
|
||||||
msg_len > BNXT_HWRM_MAX_REQ_LEN) {
|
|
||||||
short_input.req_type = ctx->req->req_type;
|
|
||||||
short_input.signature =
|
|
||||||
cpu_to_le16(SHORT_REQ_SIGNATURE_SHORT_CMD);
|
|
||||||
short_input.size = cpu_to_le16(msg_len);
|
|
||||||
short_input.req_addr = cpu_to_le64(ctx->dma_handle);
|
|
||||||
|
|
||||||
data = (u32 *)&short_input;
|
|
||||||
msg_len = sizeof(short_input);
|
|
||||||
|
|
||||||
max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure any associated DMA buffers are written before doorbell */
|
|
||||||
wmb();
|
|
||||||
|
|
||||||
/* Write request msg to hwrm channel */
|
|
||||||
__iowrite32_copy(bp->bar0 + bar_offset, data, msg_len / 4);
|
|
||||||
|
|
||||||
for (i = msg_len; i < max_req_len; i += 4)
|
|
||||||
writel(0, bp->bar0 + bar_offset + i);
|
|
||||||
|
|
||||||
ptp_read_system_prets(ctx->sts);
|
|
||||||
|
|
||||||
/* Ring channel doorbell */
|
|
||||||
writel(1, bp->bar0 + doorbell_offset);
|
|
||||||
|
|
||||||
if (!pci_is_enabled(bp->pdev)) {
|
|
||||||
rc = 0; /* don't wait for response during error recovery */
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* convert timeout to usec */
|
|
||||||
timeout = ctx->timeout * 1000;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
/* Short timeout for the first few iterations:
|
|
||||||
* number of loops = number of loops for short timeout +
|
|
||||||
* number of loops for standard timeout.
|
|
||||||
*/
|
|
||||||
tmo_count = HWRM_SHORT_TIMEOUT_COUNTER;
|
|
||||||
timeout = timeout - HWRM_SHORT_MIN_TIMEOUT * HWRM_SHORT_TIMEOUT_COUNTER;
|
|
||||||
tmo_count += DIV_ROUND_UP(timeout, HWRM_MIN_TIMEOUT);
|
|
||||||
|
|
||||||
if (le16_to_cpu(ctx->req->cmpl_ring) != INVALID_HW_RING_ID) {
|
|
||||||
/* Wait until hwrm response cmpl interrupt is processed */
|
|
||||||
while (READ_ONCE(token->state) < BNXT_HWRM_COMPLETE &&
|
|
||||||
i++ < tmo_count) {
|
|
||||||
/* Abort the wait for completion if the FW health
|
|
||||||
* check has failed.
|
|
||||||
*/
|
|
||||||
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
|
|
||||||
goto exit;
|
|
||||||
/* on first few passes, just barely sleep */
|
|
||||||
if (i < HWRM_SHORT_TIMEOUT_COUNTER)
|
|
||||||
usleep_range(HWRM_SHORT_MIN_TIMEOUT,
|
|
||||||
HWRM_SHORT_MAX_TIMEOUT);
|
|
||||||
else
|
|
||||||
usleep_range(HWRM_MIN_TIMEOUT,
|
|
||||||
HWRM_MAX_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (READ_ONCE(token->state) != BNXT_HWRM_COMPLETE) {
|
|
||||||
if (!(ctx->flags & BNXT_HWRM_CTX_SILENT))
|
|
||||||
netdev_err(bp->dev, "Resp cmpl intr err msg: 0x%x\n",
|
|
||||||
le16_to_cpu(ctx->req->req_type));
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
len = le16_to_cpu(ctx->resp->resp_len);
|
|
||||||
valid = ((u8 *)ctx->resp) + len - 1;
|
|
||||||
} else {
|
|
||||||
int j;
|
|
||||||
|
|
||||||
/* Check if response len is updated */
|
|
||||||
for (i = 0; i < tmo_count; i++) {
|
|
||||||
/* Abort the wait for completion if the FW health
|
|
||||||
* check has failed.
|
|
||||||
*/
|
|
||||||
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
if (token &&
|
|
||||||
READ_ONCE(token->state) == BNXT_HWRM_DEFERRED) {
|
|
||||||
__hwrm_release_token(bp, token);
|
|
||||||
token = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = le16_to_cpu(ctx->resp->resp_len);
|
|
||||||
if (len)
|
|
||||||
break;
|
|
||||||
/* on first few passes, just barely sleep */
|
|
||||||
if (i < HWRM_SHORT_TIMEOUT_COUNTER)
|
|
||||||
usleep_range(HWRM_SHORT_MIN_TIMEOUT,
|
|
||||||
HWRM_SHORT_MAX_TIMEOUT);
|
|
||||||
else
|
|
||||||
usleep_range(HWRM_MIN_TIMEOUT,
|
|
||||||
HWRM_MAX_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= tmo_count) {
|
|
||||||
if (!(ctx->flags & BNXT_HWRM_CTX_SILENT))
|
|
||||||
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d\n",
|
|
||||||
hwrm_total_timeout(i),
|
|
||||||
le16_to_cpu(ctx->req->req_type),
|
|
||||||
le16_to_cpu(ctx->req->seq_id), len);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last byte of resp contains valid bit */
|
|
||||||
valid = ((u8 *)ctx->resp) + len - 1;
|
|
||||||
for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
|
|
||||||
/* make sure we read from updated DMA memory */
|
|
||||||
dma_rmb();
|
|
||||||
if (*valid)
|
|
||||||
break;
|
|
||||||
usleep_range(1, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j >= HWRM_VALID_BIT_DELAY_USEC) {
|
|
||||||
if (!(ctx->flags & BNXT_HWRM_CTX_SILENT))
|
|
||||||
netdev_err(bp->dev, "Error (timeout: %d) msg {0x%x 0x%x} len:%d v:%d\n",
|
|
||||||
hwrm_total_timeout(i),
|
|
||||||
le16_to_cpu(ctx->req->req_type),
|
|
||||||
le16_to_cpu(ctx->req->seq_id), len,
|
|
||||||
*valid);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero valid bit for compatibility. Valid bit in an older spec
|
|
||||||
* may become a new field in a newer spec. We must make sure that
|
|
||||||
* a new field not implemented by old spec will read zero.
|
|
||||||
*/
|
|
||||||
*valid = 0;
|
|
||||||
rc = le16_to_cpu(ctx->resp->error_code);
|
|
||||||
if (rc && !(ctx->flags & BNXT_HWRM_CTX_SILENT)) {
|
|
||||||
if (rc == HWRM_ERR_CODE_BUSY)
|
|
||||||
netdev_warn(bp->dev, "FW returned busy, hwrm req_type 0x%x\n",
|
|
||||||
le16_to_cpu(ctx->resp->req_type));
|
|
||||||
else
|
|
||||||
netdev_err(bp->dev, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n",
|
|
||||||
le16_to_cpu(ctx->resp->req_type),
|
|
||||||
le16_to_cpu(ctx->resp->seq_id), rc);
|
|
||||||
}
|
|
||||||
#ifndef HSI_DBG_DISABLE
|
|
||||||
decode_hwrm_resp(ctx->resp);
|
|
||||||
#endif
|
|
||||||
rc = __hwrm_to_stderr(rc);
|
|
||||||
exit:
|
|
||||||
ptp_read_system_postts(ctx->sts);
|
|
||||||
if (token)
|
|
||||||
__hwrm_release_token(bp, token);
|
|
||||||
if (ctx->flags & BNXT_HWRM_CTX_OWNED)
|
|
||||||
ctx->flags |= BNXT_HWRM_RESP_DIRTY;
|
|
||||||
else
|
|
||||||
__hwrm_ctx_drop(bp, ctx);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hwrm_req_send(struct bnxt *bp, void *req)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return __hwrm_send(bp, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hwrm_req_send_silent(struct bnxt *bp, void *req)
|
|
||||||
{
|
|
||||||
hwrm_req_silence(bp, req);
|
|
||||||
return hwrm_req_send(bp, req);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
hwrm_req_dma_slice(struct bnxt *bp, void *req, u32 size, dma_addr_t *dma_handle)
|
|
||||||
{
|
|
||||||
struct bnxt_hwrm_ctx *ctx = __hwrm_ctx(bp, req);
|
|
||||||
u8 *end = ((u8 *)req) + BNXT_HWRM_DMA_SIZE;
|
|
||||||
struct input *input = req;
|
|
||||||
u8 *addr, *req_addr = req;
|
|
||||||
u32 max_offset, offset;
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
max_offset = BNXT_HWRM_DMA_SIZE - ctx->allocated;
|
|
||||||
offset = max_offset - size;
|
|
||||||
offset = ALIGN_DOWN(offset, BNXT_HWRM_DMA_ALIGN);
|
|
||||||
addr = req_addr + offset;
|
|
||||||
|
|
||||||
if (addr < req_addr + max_offset && req_addr + ctx->req_len <= addr) {
|
|
||||||
ctx->allocated = end - addr;
|
|
||||||
*dma_handle = ctx->dma_handle + offset;
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* could not suballocate from ctx buffer, try create a new mapping */
|
|
||||||
if (ctx->slice_addr) {
|
|
||||||
/* if one exists, can only be due to software bug, be loud */
|
|
||||||
netdev_err(bp->dev, "HWRM refusing to reallocate DMA slice, req_type = %u\n",
|
|
||||||
(u32)le16_to_cpu(input->req_type));
|
|
||||||
dump_stack();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = dma_alloc_coherent(&bp->pdev->dev, size, dma_handle, ctx->gfp);
|
|
||||||
|
|
||||||
if (!addr)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ctx->slice_addr = addr;
|
|
||||||
ctx->slice_size = size;
|
|
||||||
ctx->slice_handle = *dma_handle;
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
@ -1,357 +0,0 @@
|
||||||
/* Broadcom NetXtreme-C/E network driver.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Broadcom Limited
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BNXT_HWRM_H
|
|
||||||
#define BNXT_HWRM_H
|
|
||||||
|
|
||||||
#include "bnxt_hsi.h"
|
|
||||||
|
|
||||||
enum bnxt_hwrm_ctx_flags {
|
|
||||||
BNXT_HWRM_CTX_OWNED = BIT(0), /* caller owns the context */
|
|
||||||
BNXT_HWRM_CTX_SILENT = BIT(1), /* squelch firmware errors */
|
|
||||||
BNXT_HWRM_RESP_DIRTY = BIT(2), /* response contains data */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_hwrm_ctx {
|
|
||||||
u64 sentinel;
|
|
||||||
dma_addr_t dma_handle;
|
|
||||||
struct output *resp;
|
|
||||||
struct input *req;
|
|
||||||
dma_addr_t slice_handle;
|
|
||||||
void *slice_addr;
|
|
||||||
struct ptp_system_timestamp *sts;
|
|
||||||
u32 slice_size;
|
|
||||||
u32 req_len;
|
|
||||||
enum bnxt_hwrm_ctx_flags flags;
|
|
||||||
int timeout;
|
|
||||||
u32 allocated;
|
|
||||||
gfp_t gfp;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bnxt_hwrm_wait_state {
|
|
||||||
BNXT_HWRM_PENDING,
|
|
||||||
BNXT_HWRM_DEFERRED,
|
|
||||||
BNXT_HWRM_COMPLETE,
|
|
||||||
BNXT_HWRM_CANCELLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bnxt_hwrm_chnl { BNXT_HWRM_CHNL_CHIMP, BNXT_HWRM_CHNL_KONG };
|
|
||||||
|
|
||||||
struct bnxt_hwrm_wait_token {
|
|
||||||
struct rcu_head rcu;
|
|
||||||
struct hlist_node node;
|
|
||||||
enum bnxt_hwrm_wait_state state;
|
|
||||||
enum bnxt_hwrm_chnl dst;
|
|
||||||
u16 seq_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
void hwrm_update_token(struct bnxt *bp, u16 seq, enum bnxt_hwrm_wait_state s);
|
|
||||||
|
|
||||||
#define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len)
|
|
||||||
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
|
|
||||||
#define SHORT_HWRM_CMD_TIMEOUT 20
|
|
||||||
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
|
|
||||||
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
|
|
||||||
#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12)
|
|
||||||
#define BNXT_HWRM_TARGET 0xffff
|
|
||||||
#define BNXT_HWRM_NO_CMPL_RING -1
|
|
||||||
#define BNXT_HWRM_REQ_MAX_SIZE 128
|
|
||||||
#define BNXT_HWRM_DMA_SIZE (2 * PAGE_SIZE) /* space for req+resp */
|
|
||||||
#define BNXT_HWRM_RESP_RESERVED PAGE_SIZE
|
|
||||||
#define BNXT_HWRM_RESP_OFFSET (BNXT_HWRM_DMA_SIZE - \
|
|
||||||
BNXT_HWRM_RESP_RESERVED)
|
|
||||||
#define BNXT_HWRM_CTX_OFFSET (BNXT_HWRM_RESP_OFFSET - \
|
|
||||||
sizeof(struct bnxt_hwrm_ctx))
|
|
||||||
#define BNXT_HWRM_DMA_ALIGN 16
|
|
||||||
#define BNXT_HWRM_SENTINEL 0xb6e1f68a12e9a7eb /* arbitrary value */
|
|
||||||
#define BNXT_HWRM_REQS_PER_PAGE (BNXT_PAGE_SIZE / \
|
|
||||||
BNXT_HWRM_REQ_MAX_SIZE)
|
|
||||||
#define HWRM_SHORT_MIN_TIMEOUT 3
|
|
||||||
#define HWRM_SHORT_MAX_TIMEOUT 10
|
|
||||||
#define HWRM_SHORT_TIMEOUT_COUNTER 5
|
|
||||||
|
|
||||||
#define HWRM_MIN_TIMEOUT 25
|
|
||||||
#define HWRM_MAX_TIMEOUT 40
|
|
||||||
|
|
||||||
static inline int hwrm_total_timeout(int n)
|
|
||||||
{
|
|
||||||
return n <= HWRM_SHORT_TIMEOUT_COUNTER ? n * HWRM_SHORT_MIN_TIMEOUT :
|
|
||||||
HWRM_SHORT_TIMEOUT_COUNTER * HWRM_SHORT_MIN_TIMEOUT +
|
|
||||||
(n - HWRM_SHORT_TIMEOUT_COUNTER) * HWRM_MIN_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define HWRM_VALID_BIT_DELAY_USEC 150
|
|
||||||
|
|
||||||
static inline bool hwrm_req_type_cfa(u16 req_type)
|
|
||||||
{
|
|
||||||
switch (req_type) {
|
|
||||||
case HWRM_CFA_ENCAP_RECORD_ALLOC:
|
|
||||||
case HWRM_CFA_ENCAP_RECORD_FREE:
|
|
||||||
case HWRM_CFA_DECAP_FILTER_ALLOC:
|
|
||||||
case HWRM_CFA_DECAP_FILTER_FREE:
|
|
||||||
case HWRM_CFA_EM_FLOW_ALLOC:
|
|
||||||
case HWRM_CFA_EM_FLOW_FREE:
|
|
||||||
case HWRM_CFA_EM_FLOW_CFG:
|
|
||||||
case HWRM_CFA_FLOW_ALLOC:
|
|
||||||
case HWRM_CFA_FLOW_FREE:
|
|
||||||
case HWRM_CFA_FLOW_INFO:
|
|
||||||
case HWRM_CFA_FLOW_FLUSH:
|
|
||||||
case HWRM_CFA_FLOW_STATS:
|
|
||||||
case HWRM_CFA_METER_PROFILE_ALLOC:
|
|
||||||
case HWRM_CFA_METER_PROFILE_FREE:
|
|
||||||
case HWRM_CFA_METER_PROFILE_CFG:
|
|
||||||
case HWRM_CFA_METER_INSTANCE_ALLOC:
|
|
||||||
case HWRM_CFA_METER_INSTANCE_FREE:
|
|
||||||
case HWRM_CFA_EEM_QCAPS:
|
|
||||||
case HWRM_CFA_EEM_OP:
|
|
||||||
case HWRM_CFA_EEM_CFG:
|
|
||||||
case HWRM_CFA_EEM_QCFG:
|
|
||||||
case HWRM_CFA_CTX_MEM_RGTR:
|
|
||||||
case HWRM_CFA_CTX_MEM_UNRGTR:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool hwrm_req_kong(struct bnxt *bp, struct input *req)
|
|
||||||
{
|
|
||||||
return (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
|
|
||||||
(hwrm_req_type_cfa(le16_to_cpu(req->req_type)) ||
|
|
||||||
le16_to_cpu(req->target_id) == HWRM_TARGET_ID_KONG));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __hwrm_req_init() - Initialize an HWRM request.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: A pointer to the request pointer to initialize.
|
|
||||||
* @req_type: The request type. This will be converted to the little endian
|
|
||||||
* before being written to the req_type field of the returned request.
|
|
||||||
* @req_len: The length of the request to be allocated.
|
|
||||||
*
|
|
||||||
* Allocate DMA resources and initialize a new HWRM request object of the
|
|
||||||
* given type. The response address field in the request is configured with
|
|
||||||
* the DMA bus address that has been mapped for the response and the passed
|
|
||||||
* request is pointed to kernel virtual memory mapped for the request (such
|
|
||||||
* that short_input indirection can be accomplished without copying). The
|
|
||||||
* request’s target and completion ring are initialized to default values and
|
|
||||||
* can be overridden by writing to the returned request object directly.
|
|
||||||
*
|
|
||||||
* The initialized request can be further customized by writing to its fields
|
|
||||||
* directly, taking care to covert such fields to little endian. The request
|
|
||||||
* object will be consumed (and all its associated resources release) upon
|
|
||||||
* passing it to hwrm_req_send() unless ownership of the request has been
|
|
||||||
* claimed by the caller via a call to hwrm_req_hold(). If the request is not
|
|
||||||
* consumed, either because it is never sent or because ownership has been
|
|
||||||
* claimed, then it must be released by a call to hwrm_req_drop().
|
|
||||||
*
|
|
||||||
* Return: zero on success, negative error code otherwise:
|
|
||||||
* E2BIG: the type of request pointer is too large to fit.
|
|
||||||
* ENOMEM: an allocation failure occurred.
|
|
||||||
*/
|
|
||||||
int __hwrm_req_init(struct bnxt *bp, void **req, u16 req_type, u32 req_len);
|
|
||||||
#define hwrm_req_init(bp, req, req_type) \
|
|
||||||
__hwrm_req_init((bp), (void **)&(req), (req_type), sizeof(*(req)))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_hold() - Claim ownership of the request's resources.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: A pointer to the request to own. The request will no longer be
|
|
||||||
* consumed by calls to hwrm_req_send().
|
|
||||||
*
|
|
||||||
* Take ownership of the request. Ownership places responsibility on the
|
|
||||||
* caller to free the resources associated with the request via a call to
|
|
||||||
* hwrm_req_drop(). The caller taking ownership implies that a subsequent
|
|
||||||
* call to hwrm_req_send() will not consume the request (ie. sending will
|
|
||||||
* not free the associated resources if the request is owned by the caller).
|
|
||||||
* Taking ownership returns a reference to the response. Retaining and
|
|
||||||
* accessing the response data is the most common reason to take ownership
|
|
||||||
* of the request. Ownership can also be acquired in order to reuse the same
|
|
||||||
* request object across multiple invocations of hwrm_req_send().
|
|
||||||
*
|
|
||||||
* Return: A pointer to the response object.
|
|
||||||
*
|
|
||||||
* The resources associated with the response will remain available to the
|
|
||||||
* caller until ownership of the request is relinquished via a call to
|
|
||||||
* hwrm_req_drop(). It is not possible for hwrm_req_hold() to return NULL if
|
|
||||||
* a valid request is provided. A returned NULL value would imply a driver
|
|
||||||
* bug and the implementation will complain loudly in the logs to aid in
|
|
||||||
* detection. It should not be necessary to check the result for NULL.
|
|
||||||
*/
|
|
||||||
void *hwrm_req_hold(struct bnxt *bp, void *req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_drop() - Release all resources associated with the request.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to consume, releasing the associated resources. The
|
|
||||||
* request object, any slices, and its associated response are no
|
|
||||||
* longer valid.
|
|
||||||
*
|
|
||||||
* It is legal to call hwrm_req_drop() on an unowned request, provided it
|
|
||||||
* has not already been consumed by hwrm_req_send() (for example, to release
|
|
||||||
* an aborted request). A given request should not be dropped more than once,
|
|
||||||
* nor should it be dropped after having been consumed by hwrm_req_send(). To
|
|
||||||
* do so is an error (the context will not be found and a stack trace will be
|
|
||||||
* rendered in the kernel log).
|
|
||||||
*/
|
|
||||||
void hwrm_req_drop(struct bnxt *bp, void *req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_silence() - Do not log HWRM errors.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to silence.
|
|
||||||
*
|
|
||||||
* Do not print HWRM errors to the kernel log for the associated request
|
|
||||||
* during a subsequent call to hwrm_req_send(). Some requests are expected
|
|
||||||
* to fail in certain scenarios and, as such, errors should be suppressed.
|
|
||||||
*/
|
|
||||||
void hwrm_req_silence(struct bnxt *bp, void *req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_timeout() - Set the completion timeout for the request.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to set the timeout.
|
|
||||||
* @timeout: The timeout in milliseconds.
|
|
||||||
*
|
|
||||||
* Set the timeout associated with the request for subsequent calls to
|
|
||||||
* hwrm_req_send(). Some requests are long running and require a different
|
|
||||||
* timeout than the default.
|
|
||||||
*/
|
|
||||||
void hwrm_req_timeout(struct bnxt *bp, void *req, int timeout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_send() - Execute an HWRM command.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: A pointer to the request to send. The DMA resources associated with
|
|
||||||
* the request will be released (ie. the request will be consumed) unless
|
|
||||||
* ownership of the request has been assumed by the caller via a call to
|
|
||||||
* hwrm_req_hold().
|
|
||||||
*
|
|
||||||
* Send an HWRM request to the device and wait for a response. The request is
|
|
||||||
* consumed if it is not owned by the caller. This function will block until
|
|
||||||
* the request has either completed or times out due to an error.
|
|
||||||
*
|
|
||||||
* Return: A result code.
|
|
||||||
*
|
|
||||||
* The result is zero on success, otherwise the negative error code indicates
|
|
||||||
* one of the following errors:
|
|
||||||
* E2BIG: The request was too large.
|
|
||||||
* EBUSY: The firmware is in a fatal state or the request timed out
|
|
||||||
* EACCESS: HWRM access denied.
|
|
||||||
* ENOSPC: HWRM resource allocation error.
|
|
||||||
* EINVAL: Request parameters are invalid.
|
|
||||||
* ENOMEM: HWRM has no buffers.
|
|
||||||
* EAGAIN: HWRM busy or reset in progress.
|
|
||||||
* EOPNOTSUPP: Invalid request type.
|
|
||||||
* EIO: Any other error.
|
|
||||||
* Error handling is orthogonal to request ownership. An unowned request will
|
|
||||||
* still be consumed on error. If the caller owns the request, then the caller
|
|
||||||
* is responsible for releasing the resources. Otherwise, hwrm_req_send() will
|
|
||||||
* always consume the request.
|
|
||||||
*/
|
|
||||||
int hwrm_req_send(struct bnxt *bp, void *req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_send_silent() - A silent version of hwrm_req_send().
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to send without logging.
|
|
||||||
*
|
|
||||||
* The same as hwrm_req_send(), except that the request is silenced using
|
|
||||||
* hwrm_req_silence() prior the call. This version of the function is
|
|
||||||
* provided solely to preserve the legacy API’s flavor for this functionality.
|
|
||||||
*
|
|
||||||
* Return: A result code, see hwrm_req_send().
|
|
||||||
*/
|
|
||||||
int hwrm_req_send_silent(struct bnxt *bp, void *req);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_replace() - Replace request data.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to modify. A call to hwrm_req_replace() is conceptually
|
|
||||||
* an assignment of new_req to req. Subsequent calls to HWRM API functions,
|
|
||||||
* such as hwrm_req_send(), should thus use req and not new_req (in fact,
|
|
||||||
* calls to HWRM API functions will fail if non-managed request objects
|
|
||||||
* are passed).
|
|
||||||
* @len: The length of new_req.
|
|
||||||
* @new_req: The pre-built request to copy or reference.
|
|
||||||
*
|
|
||||||
* Replaces the request data in req with that of new_req. This is useful in
|
|
||||||
* scenarios where a request object has already been constructed by a third
|
|
||||||
* party prior to creating a resource managed request using hwrm_req_init().
|
|
||||||
* Depending on the length, hwrm_req_replace() will either copy the new
|
|
||||||
* request data into the DMA memory allocated for req, or it will simply
|
|
||||||
* reference the new request and use it in lieu of req during subsequent
|
|
||||||
* calls to hwrm_req_send(). The resource management is associated with
|
|
||||||
* req and is independent of and does not apply to new_req. The caller must
|
|
||||||
* ensure that the lifetime of new_req is least as long as req. Any slices
|
|
||||||
* that may have been associated with the original request are released.
|
|
||||||
*
|
|
||||||
* Return: zero on success, negative error code otherwise:
|
|
||||||
* E2BIG: Request is too large.
|
|
||||||
* EINVAL: Invalid request to modify.
|
|
||||||
*/
|
|
||||||
int hwrm_req_replace(struct bnxt *bp, void *req, void *new_req, u32 len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_alloc_flags() - Sets GFP allocation flags for slices.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request for which calls to hwrm_req_dma_slice() will have altered
|
|
||||||
* allocation flags.
|
|
||||||
* @flags: A bitmask of GFP flags. These flags are passed to
|
|
||||||
* dma_alloc_coherent() whenever it is used to allocate backing memory
|
|
||||||
* for slices. Note that calls to hwrm_req_dma_slice() will not always
|
|
||||||
* result in new allocations, however, memory suballocated from the
|
|
||||||
* request buffer is already __GFP_ZERO.
|
|
||||||
*
|
|
||||||
* Sets the GFP allocation flags associated with the request for subsequent
|
|
||||||
* calls to hwrm_req_dma_slice(). This can be useful for specifying __GFP_ZERO
|
|
||||||
* for slice allocations.
|
|
||||||
*/
|
|
||||||
void hwrm_req_alloc_flags(struct bnxt *bp, void *req, gfp_t flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_dma_slice() - Allocate a slice of DMA mapped memory.
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request for which indirect data will be associated.
|
|
||||||
* @size: The size of the allocation.
|
|
||||||
* @dma: The bus address associated with the allocation. The HWRM API has no
|
|
||||||
* knowledge about the type of the request and so cannot infer how the
|
|
||||||
* caller intends to use the indirect data. Thus, the caller is
|
|
||||||
* responsible for configuring the request object appropriately to
|
|
||||||
* point to the associated indirect memory. Note, DMA handle has the
|
|
||||||
* same definition as it does in dma_alloc_coherent(), the caller is
|
|
||||||
* responsible for endian conversions via cpu_to_le64() before assigning
|
|
||||||
* this address.
|
|
||||||
*
|
|
||||||
* Allocates DMA mapped memory for indirect data related to a request. The
|
|
||||||
* lifetime of the DMA resources will be bound to that of the request (ie.
|
|
||||||
* they will be automatically released when the request is either consumed by
|
|
||||||
* hwrm_req_send() or dropped by hwrm_req_drop()). Small allocations are
|
|
||||||
* efficiently suballocated out of the request buffer space, hence the name
|
|
||||||
* slice, while larger requests are satisfied via an underlying call to
|
|
||||||
* dma_alloc_coherent(). Multiple suballocations are supported, however, only
|
|
||||||
* one externally mapped region is.
|
|
||||||
*
|
|
||||||
* Return: The kernel virtual address of the DMA mapping.
|
|
||||||
*/
|
|
||||||
void *hwrm_req_dma_slice(struct bnxt *bp, void *req, u32 size, dma_addr_t *dma);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hwrm_req_capture_ts() - Get system time into PTP provided time structure
|
|
||||||
* @bp: The driver context.
|
|
||||||
* @req: The request to query free running timer of the NIC
|
|
||||||
* @sts: System provided ptp_system_timestamp structure
|
|
||||||
*
|
|
||||||
* PTP's gettimex64() optionally provides a system timestamp structure that
|
|
||||||
* driver should update. This function sets the sts member of bnxt_hwrm_ctx
|
|
||||||
* associated with the request. The __hwrm_send() will eventually update the
|
|
||||||
* pre and post system time in this structure when executing the gettimex64()
|
|
||||||
*/
|
|
||||||
void hwrm_req_capture_ts(struct bnxt *bp, void *req, struct ptp_system_timestamp *sts);
|
|
||||||
#endif
|
|
||||||
|
|
@ -18,13 +18,10 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/dma-buf.h>
|
|
||||||
|
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_eem.h"
|
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_ulp.h"
|
#include "bnxt_ulp.h"
|
||||||
#include "bnxt_lfc.h"
|
#include "bnxt_lfc.h"
|
||||||
#include "bnxt_lfc_ioctl.h"
|
#include "bnxt_lfc_ioctl.h"
|
||||||
|
|
@ -549,394 +546,6 @@ err1:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bnxt_eem_dmabuf_release(struct bnxt *bp,
|
|
||||||
struct bnxt_eem_dmabuf_info *dmabuf_priv)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_dmabuf_info *priv;
|
|
||||||
int tbl_type;
|
|
||||||
int dir;
|
|
||||||
|
|
||||||
for (dir = BNXT_EEM_DIR_TX; dir < BNXT_EEM_NUM_DIR; dir++) {
|
|
||||||
for (tbl_type = 0; tbl_type < MAX_TABLE; tbl_type++) {
|
|
||||||
if (tbl_type == EFC_TABLE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
priv = dmabuf_priv + (dir * MAX_TABLE + tbl_type);
|
|
||||||
netdev_dbg(bp->dev,
|
|
||||||
"Dir:%d, tbl_type:%d, priv->fd %d\n",
|
|
||||||
dir, priv->type, priv->fd);
|
|
||||||
|
|
||||||
if (priv->type != MAX_TABLE) {
|
|
||||||
if (priv->buf)
|
|
||||||
dma_buf_put(priv->buf);
|
|
||||||
|
|
||||||
if (priv->pages) {
|
|
||||||
sg_free_table(&priv->sg);
|
|
||||||
kfree(priv->pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->buf = NULL;
|
|
||||||
priv->fd = 0;
|
|
||||||
priv->pages = NULL;
|
|
||||||
priv->type = MAX_TABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dmabuf_priv->dir &= ~(1 << dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_dmabuf_close(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_dmabuf_info *dmabuf_priv;
|
|
||||||
|
|
||||||
if (!bp->dmabuf_data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dmabuf_priv = bp->dmabuf_data;
|
|
||||||
bnxt_eem_dmabuf_release(bp, dmabuf_priv);
|
|
||||||
|
|
||||||
if (!dmabuf_priv->dir) {
|
|
||||||
kfree(dmabuf_priv);
|
|
||||||
bp->dmabuf_data = NULL;
|
|
||||||
netdev_dbg(bp->dev, "release dmabuf data\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t bnxt_lfc_process_dmabuf_close(struct bnxt_lfc_dev *blfc_dev)
|
|
||||||
{
|
|
||||||
struct bnxt *bp = blfc_dev->bp;
|
|
||||||
|
|
||||||
return bnxt_eem_dmabuf_close(bp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_dmabuf_reg(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_dmabuf_info *priv;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (bp->dmabuf_data) {
|
|
||||||
bnxt_eem_dmabuf_close(bp);
|
|
||||||
netdev_warn(bp->dev, "clear existed dmabuf\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
priv = kzalloc(sizeof(*priv) * BNXT_EEM_NUM_DIR * MAX_TABLE,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!priv)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
bp->dmabuf_data = priv;
|
|
||||||
for (i = 0; i < BNXT_EEM_NUM_DIR * MAX_TABLE; i++) {
|
|
||||||
priv[i].dev = &bp->pdev->dev;
|
|
||||||
priv[i].type = MAX_TABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_DMABUF_ATTACH_DEV
|
|
||||||
static int bnxt_dmabuf_attach(struct dma_buf *buf, struct device *dev,
|
|
||||||
struct dma_buf_attachment *attach)
|
|
||||||
#else
|
|
||||||
static int bnxt_dmabuf_attach(struct dma_buf *buf,
|
|
||||||
struct dma_buf_attachment *attach)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_detach(struct dma_buf *buf,
|
|
||||||
struct dma_buf_attachment *attach)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
struct sg_table *bnxt_dmabuf_map_dma_buf(struct dma_buf_attachment *attach,
|
|
||||||
enum dma_data_direction dir)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_unmap_dma_buf(struct dma_buf_attachment *attach,
|
|
||||||
struct sg_table *sgt,
|
|
||||||
enum dma_data_direction dir)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_release(struct dma_buf *buf)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_DMABUF_KMAP_ATOMIC) || defined(HAVE_DMABUF_KMAP) || \
|
|
||||||
defined(HAVE_DMABUF_MAP_ATOMIC) || defined(HAVE_DMABUF_MAP)
|
|
||||||
static void *bnxt_dmabuf_kmap(struct dma_buf *buf, unsigned long page)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_kunmap(struct dma_buf *buf, unsigned long page,
|
|
||||||
void *vaddr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_vm_open(struct vm_area_struct *vma)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_vm_close(struct vm_area_struct *vma)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct vm_operations_struct dmabuf_vm_ops = {
|
|
||||||
.open = bnxt_dmabuf_vm_open,
|
|
||||||
.close = bnxt_dmabuf_vm_close,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int bnxt_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
|
|
||||||
{
|
|
||||||
pgprot_t prot = vm_get_page_prot(vma->vm_flags);
|
|
||||||
struct bnxt_eem_dmabuf_info *priv = buf->priv;
|
|
||||||
int page_block = vma->vm_pgoff / MAX_CTX_PAGES;
|
|
||||||
int page_no = vma->vm_pgoff % MAX_CTX_PAGES;
|
|
||||||
struct bnxt_ctx_pg_info *ctx_pg;
|
|
||||||
dma_addr_t pg_phys;
|
|
||||||
|
|
||||||
vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND;
|
|
||||||
vma->vm_ops = &dmabuf_vm_ops;
|
|
||||||
vma->vm_private_data = priv;
|
|
||||||
vma->vm_page_prot = pgprot_writecombine(prot);
|
|
||||||
|
|
||||||
ctx_pg = priv->tbl->ctx_pg_tbl[page_block];
|
|
||||||
pg_phys = ctx_pg->ctx_dma_arr[page_no];
|
|
||||||
return remap_pfn_range(vma, vma->vm_start, pg_phys >> PAGE_SHIFT,
|
|
||||||
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *bnxt_dmabuf_vmap(struct dma_buf *buf)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bnxt_dmabuf_vunmap(struct dma_buf *buf, void *vaddr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dma_buf_ops bnxt_dmabuf_ops = {
|
|
||||||
.attach = bnxt_dmabuf_attach,
|
|
||||||
.detach = bnxt_dmabuf_detach,
|
|
||||||
.map_dma_buf = bnxt_dmabuf_map_dma_buf,
|
|
||||||
.unmap_dma_buf = bnxt_dmabuf_unmap_dma_buf,
|
|
||||||
.release = bnxt_dmabuf_release,
|
|
||||||
#ifdef HAVE_DMABUF_KMAP_ATOMIC
|
|
||||||
.kmap_atomic = bnxt_dmabuf_kmap,
|
|
||||||
.kunmap_atomic = bnxt_dmabuf_kunmap,
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DMABUF_KMAP
|
|
||||||
.kmap = bnxt_dmabuf_kmap,
|
|
||||||
.kunmap = bnxt_dmabuf_kunmap,
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DMABUF_MAP_ATOMIC
|
|
||||||
.map_atomic = bnxt_dmabuf_kmap,
|
|
||||||
.unmap_atomic = bnxt_dmabuf_kunmap,
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DMABUF_MAP
|
|
||||||
.map = bnxt_dmabuf_kmap,
|
|
||||||
.unmap = bnxt_dmabuf_kunmap,
|
|
||||||
#endif
|
|
||||||
.mmap = bnxt_dmabuf_mmap,
|
|
||||||
.vmap = bnxt_dmabuf_vmap,
|
|
||||||
.vunmap = bnxt_dmabuf_vunmap,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int bnxt_dmabuf_page_map(struct bnxt *bp, int dir, int tbl_type,
|
|
||||||
struct bnxt_eem_dmabuf_info *priv)
|
|
||||||
{
|
|
||||||
struct bnxt_ctx_pg_info *pg_tbl = NULL;
|
|
||||||
struct bnxt_ctx_pg_info *ctx_pg;
|
|
||||||
int page_no = 0;
|
|
||||||
int ctx_block;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
priv->tbl = &bp->eem_info->eem_ctx_info[dir].eem_tables[tbl_type];
|
|
||||||
ctx_pg = &bp->eem_info->eem_ctx_info[dir].eem_tables[tbl_type];
|
|
||||||
|
|
||||||
if (!ctx_pg->nr_pages)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
priv->pg_count = ctx_pg->nr_pages;
|
|
||||||
priv->pages = kcalloc(priv->pg_count, sizeof(*priv->pages), GFP_KERNEL);
|
|
||||||
if (!priv->pages)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ctx_block = priv->pg_count / MAX_CTX_PAGES;
|
|
||||||
for (i = 0; i < ctx_block; i++) {
|
|
||||||
pg_tbl = ctx_pg->ctx_pg_tbl[i];
|
|
||||||
if (pg_tbl) {
|
|
||||||
for (j = 0; j < MAX_CTX_PAGES; j++) {
|
|
||||||
priv->pages[page_no] =
|
|
||||||
virt_to_page(pg_tbl->ctx_pg_arr[j]);
|
|
||||||
page_no++;
|
|
||||||
if (page_no == priv->pg_count)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sg_alloc_table_from_pages(&priv->sg, priv->pages, priv->pg_count,
|
|
||||||
0, (priv->pg_count << PAGE_SHIFT),
|
|
||||||
GFP_KERNEL)) {
|
|
||||||
kfree(priv->pages);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dma_map_sg(priv->dev, priv->sg.sgl,
|
|
||||||
priv->sg.nents, DMA_BIDIRECTIONAL)) {
|
|
||||||
sg_free_table(&priv->sg);
|
|
||||||
kfree(priv->pages);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_dmabuf_export(struct bnxt_eem_dmabuf_info *priv)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
priv->buf = dma_buf_export_attr(priv, priv->pg_count, &bnxt_dmabuf_ops);
|
|
||||||
if (!priv->buf)
|
|
||||||
rc = -EBUSY;
|
|
||||||
|
|
||||||
if (IS_ERR(priv->buf))
|
|
||||||
rc = PTR_ERR(priv->buf);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_dmabuf_export(struct bnxt *bp, u32 flags)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_dmabuf_info *dmabuf_priv;
|
|
||||||
struct bnxt_eem_dmabuf_info *priv;
|
|
||||||
int tbl_type;
|
|
||||||
int dir;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
dmabuf_priv = bp->dmabuf_data;
|
|
||||||
for (dir = BNXT_EEM_DIR_TX; dir < BNXT_EEM_NUM_DIR; dir++) {
|
|
||||||
for (tbl_type = KEY0_TABLE; tbl_type < MAX_TABLE; tbl_type++) {
|
|
||||||
if (tbl_type == EFC_TABLE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
priv = dmabuf_priv + (dir * MAX_TABLE + tbl_type);
|
|
||||||
netdev_dbg(bp->dev,
|
|
||||||
"export: dir %d, tbl:%d\n", dir, tbl_type);
|
|
||||||
|
|
||||||
if (priv->type != MAX_TABLE && priv->fd) {
|
|
||||||
rc = -EIO;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bnxt_dmabuf_page_map(bp, dir, tbl_type, priv);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = bnxt_dmabuf_export(priv);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
priv->type = tbl_type;
|
|
||||||
}
|
|
||||||
dmabuf_priv->dir |= (1 << dir);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bnxt_eem_dmabuf_fd(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
struct bnxt_eem_dmabuf_info *priv;
|
|
||||||
int fd;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!bp->dmabuf_data) {
|
|
||||||
netdev_err(bp->dev, "Failed to export dmabuf file");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (priv = bp->dmabuf_data, i = 0;
|
|
||||||
i < BNXT_EEM_NUM_DIR * MAX_TABLE; i++, priv++) {
|
|
||||||
if (!priv->buf) {
|
|
||||||
priv->fd = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_dma_buf(priv->buf);
|
|
||||||
fd = dma_buf_fd(priv->buf, O_ACCMODE);
|
|
||||||
if (fd < 0) {
|
|
||||||
dma_buf_put(priv->buf);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
priv->fd = fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_eem_dmabuf_export_fd(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bnxt_eem_dmabuf_reg(bp);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev, "dmabuf private data initial failed\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bnxt_eem_dmabuf_export(bp, O_ACCMODE);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev, "prepare dmabuf fail.\n");
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bnxt_eem_dmabuf_fd(bp);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev, "dmabuf fd fail.\n");
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
clean:
|
|
||||||
bnxt_eem_dmabuf_close(bp);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int32_t bnxt_lfc_process_dmabuf_export(struct bnxt_lfc_dev *blfc_dev,
|
|
||||||
struct bnxt_lfc_req *lfc_req)
|
|
||||||
{
|
|
||||||
struct bnxt_lfc_dmabuf_fd dmabuf_fd;
|
|
||||||
struct bnxt_eem_dmabuf_info *priv;
|
|
||||||
struct bnxt *bp = blfc_dev->bp;
|
|
||||||
int32_t rc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rc = bnxt_eem_dmabuf_export_fd(bp);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
for (priv = bp->dmabuf_data, i = 0;
|
|
||||||
i < BNXT_LFC_EEM_MAX_TABLE; i++, priv++)
|
|
||||||
dmabuf_fd.fd[i] = priv->fd;
|
|
||||||
|
|
||||||
rc = copy_to_user(lfc_req->req.eem_dmabuf_export_fd_req.dma_fd,
|
|
||||||
&dmabuf_fd, sizeof(dmabuf_fd));
|
|
||||||
if (rc)
|
|
||||||
rc = -EFAULT;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t bnxt_lfc_process_req(struct bnxt_lfc_dev *blfc_dev,
|
static int32_t bnxt_lfc_process_req(struct bnxt_lfc_dev *blfc_dev,
|
||||||
struct bnxt_lfc_req *lfc_req)
|
struct bnxt_lfc_req *lfc_req)
|
||||||
{
|
{
|
||||||
|
|
@ -957,12 +566,6 @@ static int32_t bnxt_lfc_process_req(struct bnxt_lfc_dev *blfc_dev,
|
||||||
case BNXT_LFC_GENERIC_HWRM_REQ:
|
case BNXT_LFC_GENERIC_HWRM_REQ:
|
||||||
rc = bnxt_lfc_process_hwrm(blfc_dev, lfc_req);
|
rc = bnxt_lfc_process_hwrm(blfc_dev, lfc_req);
|
||||||
break;
|
break;
|
||||||
case BNXT_LFC_DMABUF_CLOSE_REQ:
|
|
||||||
rc = bnxt_lfc_process_dmabuf_close(blfc_dev);
|
|
||||||
break;
|
|
||||||
case BNXT_LFC_EEM_DMABUF_EXPORT_FD_REQ:
|
|
||||||
rc = bnxt_lfc_process_dmabuf_export(blfc_dev, lfc_req);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
BNXT_LFC_DEBUG(&blfc_dev->pdev->dev,
|
BNXT_LFC_DEBUG(&blfc_dev->pdev->dev,
|
||||||
"No valid request found\n");
|
"No valid request found\n");
|
||||||
|
|
@ -1090,7 +693,6 @@ not_taken:
|
||||||
|
|
||||||
if (bnxt_lfc_is_valid_pdev(blfc_dev->pdev) != true) {
|
if (bnxt_lfc_is_valid_pdev(blfc_dev->pdev) != true) {
|
||||||
mutex_unlock(&blfc_global_dev.bnxt_lfc_lock);
|
mutex_unlock(&blfc_global_dev.bnxt_lfc_lock);
|
||||||
kfree(blfc_dev);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1101,7 +703,6 @@ not_taken:
|
||||||
pci_dev_put(blfc_dev->pdev);
|
pci_dev_put(blfc_dev->pdev);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
mutex_unlock(&blfc_global_dev.bnxt_lfc_lock);
|
mutex_unlock(&blfc_global_dev.bnxt_lfc_lock);
|
||||||
kfree(blfc_dev);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,18 +82,6 @@ struct bnxt_gloabl_dev {
|
||||||
struct mutex bnxt_lfc_lock;
|
struct mutex bnxt_lfc_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bnxt_eem_dmabuf_info {
|
|
||||||
int fd;
|
|
||||||
u32 dir;
|
|
||||||
int type;
|
|
||||||
int pg_count;
|
|
||||||
struct dma_buf *buf;
|
|
||||||
struct sg_table sg;
|
|
||||||
struct device *dev;
|
|
||||||
struct page **pages;
|
|
||||||
struct bnxt_ctx_pg_info *tbl;
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t bnxt_lfc_init(void);
|
int32_t bnxt_lfc_init(void);
|
||||||
void bnxt_lfc_exit(void);
|
void bnxt_lfc_exit(void);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ enum bnxt_lfc_req_type {
|
||||||
BNXT_LFC_NVM_SET_VAR_REQ,
|
BNXT_LFC_NVM_SET_VAR_REQ,
|
||||||
BNXT_LFC_NVM_FLUSH_REQ,
|
BNXT_LFC_NVM_FLUSH_REQ,
|
||||||
BNXT_LFC_GENERIC_HWRM_REQ,
|
BNXT_LFC_GENERIC_HWRM_REQ,
|
||||||
BNXT_LFC_EEM_DMABUF_EXPORT_FD_REQ,
|
|
||||||
BNXT_LFC_DMABUF_CLOSE_REQ,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bnxt_lfc_req_hdr {
|
struct bnxt_lfc_req_hdr {
|
||||||
|
|
@ -95,23 +93,11 @@ struct bnxt_lfc_generic_msg {
|
||||||
__u32 value;
|
__u32 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BNXT_LFC_EEM_MAX_TABLE 8
|
|
||||||
|
|
||||||
struct bnxt_lfc_dmabuf_fd {
|
|
||||||
int fd[BNXT_LFC_EEM_MAX_TABLE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_lfc_eem_dmabuf_export_fd_req {
|
|
||||||
void __user *dma_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bnxt_lfc_req {
|
struct bnxt_lfc_req {
|
||||||
struct bnxt_lfc_req_hdr hdr;
|
struct bnxt_lfc_req_hdr hdr;
|
||||||
union {
|
union {
|
||||||
struct bnxt_lfc_nvm_get_var_req nvm_get_var_req;
|
struct bnxt_lfc_nvm_get_var_req nvm_get_var_req;
|
||||||
struct bnxt_lfc_nvm_set_var_req nvm_set_var_req;
|
struct bnxt_lfc_nvm_set_var_req nvm_set_var_req;
|
||||||
struct bnxt_lfc_eem_dmabuf_export_fd_req
|
|
||||||
eem_dmabuf_export_fd_req;
|
|
||||||
__u64 hreq; /* Pointer to "struct blfc_fw_msg" */
|
__u64 hreq; /* Pointer to "struct blfc_fw_msg" */
|
||||||
} req;
|
} req;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt_netlink.h"
|
#include "bnxt_netlink.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
|
|
||||||
/* attribute policy */
|
/* attribute policy */
|
||||||
static struct nla_policy bnxt_netlink_policy[BNXT_NUM_ATTRS] = {
|
static struct nla_policy bnxt_netlink_policy[BNXT_NUM_ATTRS] = {
|
||||||
|
|
@ -87,13 +86,14 @@ err_inval:
|
||||||
static int bnxt_netlink_hwrm(struct sk_buff *skb, struct genl_info *info)
|
static int bnxt_netlink_hwrm(struct sk_buff *skb, struct genl_info *info)
|
||||||
{
|
{
|
||||||
struct nlattr **a = info->attrs;
|
struct nlattr **a = info->attrs;
|
||||||
struct net_device *dev = NULL;
|
int len;
|
||||||
struct sk_buff *reply = NULL;
|
struct sk_buff *reply = NULL;
|
||||||
struct input *req, *nl_req;
|
struct input *req;
|
||||||
struct bnxt *bp = NULL;
|
|
||||||
struct output *resp;
|
struct output *resp;
|
||||||
int len, rc;
|
struct bnxt *bp = NULL;
|
||||||
|
int rc = 0;
|
||||||
void *hdr;
|
void *hdr;
|
||||||
|
struct net_device *dev = NULL;
|
||||||
|
|
||||||
rc = bnxt_parse_attrs(a, &bp, &dev);
|
rc = bnxt_parse_attrs(a, &bp, &dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
@ -104,20 +104,28 @@ static int bnxt_netlink_hwrm(struct sk_buff *skb, struct genl_info *info)
|
||||||
goto err_rc;
|
goto err_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bp->hwrm_dma_pool) {
|
if (!bp->hwrm_cmd_resp_addr) {
|
||||||
netdev_warn(bp->dev, "HWRM interface not currently available on %s\n",
|
netdev_warn(bp->dev, "HWRM interface not currently available on %s\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto err_rc;
|
goto err_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL &&
|
||||||
|
!bp->hwrm_cmd_kong_resp_addr) {
|
||||||
|
netdev_warn(bp->dev, "HWRM Kong interface not currently available on %s\n",
|
||||||
|
dev->name);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto err_rc;
|
||||||
|
}
|
||||||
|
|
||||||
if (!a[BNXT_ATTR_REQUEST]) {
|
if (!a[BNXT_ATTR_REQUEST]) {
|
||||||
netdev_warn(bp->dev, "No request specified\n");
|
netdev_warn(bp->dev, "No request specified\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto err_rc;
|
goto err_rc;
|
||||||
}
|
}
|
||||||
len = nla_len(a[BNXT_ATTR_REQUEST]);
|
len = nla_len(a[BNXT_ATTR_REQUEST]);
|
||||||
nl_req = nla_data(a[BNXT_ATTR_REQUEST]);
|
req = nla_data(a[BNXT_ATTR_REQUEST]);
|
||||||
|
|
||||||
reply = genlmsg_new(PAGE_SIZE, GFP_KERNEL);
|
reply = genlmsg_new(PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
|
|
@ -126,16 +134,9 @@ static int bnxt_netlink_hwrm(struct sk_buff *skb, struct genl_info *info)
|
||||||
goto err_rc;
|
goto err_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, nl_req->req_type);
|
bnxt_hwrm_cmd_hdr_init(bp, req, req->req_type, -1, -1);
|
||||||
if (rc)
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
goto err_rc;
|
rc = _hwrm_send_message_silent(bp, req, len, HWRM_CMD_TIMEOUT);
|
||||||
|
|
||||||
rc = hwrm_req_replace(bp, req, nl_req, len);
|
|
||||||
if (rc)
|
|
||||||
goto err_rc;
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send_silent(bp, req);
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
/*
|
/*
|
||||||
* Indicate success for the hwrm transport, while letting
|
* Indicate success for the hwrm transport, while letting
|
||||||
|
|
@ -149,14 +150,15 @@ static int bnxt_netlink_hwrm(struct sk_buff *skb, struct genl_info *info)
|
||||||
}
|
}
|
||||||
hdr = genlmsg_put_reply(reply, info, &bnxt_netlink_family, 0,
|
hdr = genlmsg_put_reply(reply, info, &bnxt_netlink_family, 0,
|
||||||
BNXT_CMD_HWRM);
|
BNXT_CMD_HWRM);
|
||||||
|
resp = (struct output *)bnxt_get_hwrm_resp_addr(bp, req);
|
||||||
if (nla_put(reply, BNXT_ATTR_RESPONSE, resp->resp_len, resp)) {
|
if (nla_put(reply, BNXT_ATTR_RESPONSE, resp->resp_len, resp)) {
|
||||||
netdev_warn(bp->dev, "No space for response attribte\n");
|
netdev_warn(bp->dev, "No space for response attribte\n");
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_rc;
|
goto err_rc;
|
||||||
}
|
}
|
||||||
genlmsg_end(reply, hdr);
|
genlmsg_end(reply, hdr);
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
|
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_ptp.h"
|
#include "bnxt_ptp.h"
|
||||||
|
|
||||||
#ifdef HAVE_IEEE1588_SUPPORT
|
#ifdef HAVE_IEEE1588_SUPPORT
|
||||||
|
|
@ -31,68 +30,11 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
|
||||||
ptp_info);
|
ptp_info);
|
||||||
u64 ns = timespec64_to_ns(ts);
|
u64 ns = timespec64_to_ns(ts);
|
||||||
|
|
||||||
|
ns = timespec64_to_ns(ts);
|
||||||
timecounter_init(&ptp->tc, &ptp->cc, ns);
|
timecounter_init(&ptp->tc, &ptp->cc, ns);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
|
|
||||||
struct ptp_system_timestamp *sts)
|
|
||||||
{
|
|
||||||
struct hwrm_port_ts_query_output *resp;
|
|
||||||
struct hwrm_port_ts_query_input *req;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_PORT_TS_QUERY);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->flags = cpu_to_le32(flags);
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
if (sts)
|
|
||||||
hwrm_req_capture_ts(bp, req, sts);
|
|
||||||
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
if (rc) {
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
*ts = le64_to_cpu(resp->ptp_msg_ts);
|
|
||||||
hwrm_req_drop(bp, req);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_ptp_get_current_time(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
u32 flags = PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME;
|
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
|
||||||
|
|
||||||
if (!ptp)
|
|
||||||
return 0;
|
|
||||||
ptp->old_time = ptp->current_time;
|
|
||||||
return bnxt_hwrm_port_ts_query(bp, flags, &ptp->current_time, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_PTP_GETTIMEX64
|
|
||||||
static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info,
|
|
||||||
struct timespec64 *ts,
|
|
||||||
struct ptp_system_timestamp *sts)
|
|
||||||
{
|
|
||||||
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
|
|
||||||
ptp_info);
|
|
||||||
u32 flags = PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME;
|
|
||||||
u64 ns, cycles;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_port_ts_query(ptp->bp, flags, &cycles, sts);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
ns = timecounter_cyc2time(&ptp->tc, cycles);
|
|
||||||
*ts = ns_to_timespec64(ns);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int bnxt_ptp_gettime(struct ptp_clock_info *ptp_info,
|
static int bnxt_ptp_gettime(struct ptp_clock_info *ptp_info,
|
||||||
struct timespec64 *ts)
|
struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
|
|
@ -104,7 +46,7 @@ static int bnxt_ptp_gettime(struct ptp_clock_info *ptp_info,
|
||||||
*ts = ns_to_timespec64(ns);
|
*ts = ns_to_timespec64(ns);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
|
static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
|
||||||
{
|
{
|
||||||
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
|
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
|
||||||
|
|
@ -123,24 +65,6 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
|
||||||
s32 best_dif = BNXT_MAX_PHC_DRIFT;
|
s32 best_dif = BNXT_MAX_PHC_DRIFT;
|
||||||
u32 drift_sign = 1;
|
u32 drift_sign = 1;
|
||||||
|
|
||||||
if (ptp->bp->flags & BNXT_FLAG_CHIP_P5) {
|
|
||||||
struct hwrm_port_mac_cfg_input *req;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->ptp_freq_adj_ppb = ppb;
|
|
||||||
req->enables =
|
|
||||||
cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
|
|
||||||
rc = hwrm_req_send(ptp->bp, req);
|
|
||||||
if (rc)
|
|
||||||
netdev_err(ptp->bp->dev,
|
|
||||||
"ptp adjfreq failed. rc = %d\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Frequency adjustment requires programming 3 values:
|
/* Frequency adjustment requires programming 3 values:
|
||||||
* 1-bit direction
|
* 1-bit direction
|
||||||
* 5-bit adjustment step in 1 ns unit
|
* 5-bit adjustment step in 1 ns unit
|
||||||
|
|
@ -204,7 +128,7 @@ static void bnxt_clr_rx_ts(struct bnxt *bp)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
u32 fifo;
|
u32 fifo;
|
||||||
|
|
||||||
if (!ptp || (bp->flags & BNXT_FLAG_CHIP_P5))
|
if (!ptp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
port_id = pf->port_id;
|
port_id = pf->port_id;
|
||||||
|
|
@ -219,17 +143,14 @@ static void bnxt_clr_rx_ts(struct bnxt *bp)
|
||||||
|
|
||||||
static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
|
static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
|
struct hwrm_port_mac_cfg_input req = {0};
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
||||||
struct hwrm_port_mac_cfg_input *req;
|
|
||||||
u32 flags = 0;
|
u32 flags = 0;
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!ptp)
|
if (!ptp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_CFG, -1, -1);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (ptp->rx_filter)
|
if (ptp->rx_filter)
|
||||||
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
|
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE;
|
||||||
|
|
@ -239,11 +160,12 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
|
||||||
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
|
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE;
|
||||||
else
|
else
|
||||||
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
|
flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE;
|
||||||
req->flags = cpu_to_le32(flags);
|
req.flags = cpu_to_le32(flags);
|
||||||
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
|
req.enables = cpu_to_le32(
|
||||||
req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
|
PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE);
|
||||||
|
req.rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
|
||||||
|
|
||||||
return hwrm_req_send(bp, req);
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
||||||
|
|
@ -399,19 +321,8 @@ static u64 bnxt_cc_read(const struct cyclecounter *cc)
|
||||||
struct bnxt *bp = ptp->bp;
|
struct bnxt *bp = ptp->bp;
|
||||||
u64 ns;
|
u64 ns;
|
||||||
|
|
||||||
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
ns = readl(bp->bar0 + BNXT_GRCPF_REG_SYNC_TIME);
|
||||||
u32 flags = PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME;
|
ns |= (u64)readl(bp->bar0 + BNXT_GRCPF_REG_SYNC_TIME + 4) << 32;
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_port_ts_query(bp, flags, &ns, NULL);
|
|
||||||
if (rc)
|
|
||||||
netdev_err(bp->dev, "TS query for cc_read failed rc = %x\n",
|
|
||||||
rc);
|
|
||||||
} else {
|
|
||||||
ns = readl(bp->bar0 + BNXT_GRCPF_REG_SYNC_TIME);
|
|
||||||
ns |= (u64)readl(bp->bar0 + BNXT_GRCPF_REG_SYNC_TIME + 4) << 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,80 +374,6 @@ int bnxt_get_rx_ts(struct bnxt *bp, u64 *ts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bnxt_ptp_ts_task(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct bnxt_ptp_cfg *ptp = container_of(work, struct bnxt_ptp_cfg,
|
|
||||||
ptp_ts_task);
|
|
||||||
u32 flags = PORT_TS_QUERY_REQ_FLAGS_PATH_TX;
|
|
||||||
struct skb_shared_hwtstamps timestamp;
|
|
||||||
struct bnxt *bp = ptp->bp;
|
|
||||||
u64 ts = 0, ns = 0;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!ptp->tx_skb)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_port_ts_query(bp, flags, &ts, NULL);
|
|
||||||
if (rc) {
|
|
||||||
netdev_err(bp->dev, "TS query for TX timer failed rc = %x\n",
|
|
||||||
rc);
|
|
||||||
} else {
|
|
||||||
memset(×tamp, 0, sizeof(timestamp));
|
|
||||||
ns = timecounter_cyc2time(&ptp->tc, ts);
|
|
||||||
timestamp.hwtstamp = ns_to_ktime(ns);
|
|
||||||
skb_tstamp_tx(ptp->tx_skb, ×tamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_kfree_skb_any(ptp->tx_skb);
|
|
||||||
ptp->tx_skb = NULL;
|
|
||||||
atomic_inc(&bp->ptp_cfg->tx_avail);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
|
||||||
|
|
||||||
if (ptp->tx_skb) {
|
|
||||||
netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n");
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
ptp->tx_skb = skb;
|
|
||||||
schedule_work(&ptp->ptp_ts_task);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts)
|
|
||||||
{
|
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
|
||||||
u64 time;
|
|
||||||
|
|
||||||
time = READ_ONCE(ptp->old_time);
|
|
||||||
*ts = (time & BNXT_HI_TIMER_MASK) | pkt_ts;
|
|
||||||
if (pkt_ts < (time & BNXT_LO_TIMER_MASK))
|
|
||||||
*ts += BNXT_LO_TIMER_MASK + 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_ptp_start(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!ptp)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
|
||||||
u32 flags = PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bnxt_hwrm_port_ts_query(bp, flags, &ptp->current_time,
|
|
||||||
NULL);
|
|
||||||
ptp->old_time = ptp->current_time;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct ptp_clock_info bnxt_ptp_caps = {
|
static const struct ptp_clock_info bnxt_ptp_caps = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "bnxt clock",
|
.name = "bnxt clock",
|
||||||
|
|
@ -548,11 +385,7 @@ static const struct ptp_clock_info bnxt_ptp_caps = {
|
||||||
.pps = 0,
|
.pps = 0,
|
||||||
.adjfreq = bnxt_ptp_adjfreq,
|
.adjfreq = bnxt_ptp_adjfreq,
|
||||||
.adjtime = bnxt_ptp_adjtime,
|
.adjtime = bnxt_ptp_adjtime,
|
||||||
#ifdef HAVE_PTP_GETTIMEX64
|
.gettime64 = bnxt_ptp_gettime,
|
||||||
.gettimex64 = bnxt_ptp_gettimex,
|
|
||||||
#else
|
|
||||||
.gettime64 = bnxt_ptp_gettime,
|
|
||||||
#endif
|
|
||||||
.settime64 = bnxt_ptp_settime,
|
.settime64 = bnxt_ptp_settime,
|
||||||
.enable = bnxt_ptp_enable,
|
.enable = bnxt_ptp_enable,
|
||||||
};
|
};
|
||||||
|
|
@ -560,17 +393,13 @@ static const struct ptp_clock_info bnxt_ptp_caps = {
|
||||||
int bnxt_ptp_init(struct bnxt *bp)
|
int bnxt_ptp_init(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!ptp)
|
if (!ptp)
|
||||||
return 0;
|
return 0;
|
||||||
|
rc = bnxt_map_ptp_regs(bp);
|
||||||
if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
|
if (rc)
|
||||||
int rc;
|
return rc;
|
||||||
|
|
||||||
rc = bnxt_map_ptp_regs(bp);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
|
atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
|
||||||
|
|
||||||
|
|
@ -587,7 +416,6 @@ int bnxt_ptp_init(struct bnxt *bp)
|
||||||
if (IS_ERR(ptp->ptp_clock))
|
if (IS_ERR(ptp->ptp_clock))
|
||||||
ptp->ptp_clock = NULL;
|
ptp->ptp_clock = NULL;
|
||||||
|
|
||||||
INIT_WORK(&ptp->ptp_ts_task, bnxt_ptp_ts_task);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -601,22 +429,12 @@ void bnxt_ptp_free(struct bnxt *bp)
|
||||||
if (ptp->ptp_clock)
|
if (ptp->ptp_clock)
|
||||||
ptp_clock_unregister(ptp->ptp_clock);
|
ptp_clock_unregister(ptp->ptp_clock);
|
||||||
|
|
||||||
cancel_work_sync(&ptp->ptp_ts_task);
|
|
||||||
ptp->ptp_clock = NULL;
|
ptp->ptp_clock = NULL;
|
||||||
if (ptp->tx_skb) {
|
|
||||||
dev_kfree_skb_any(ptp->tx_skb);
|
|
||||||
ptp->tx_skb = NULL;
|
|
||||||
}
|
|
||||||
bnxt_unmap_ptp_regs(bp);
|
bnxt_unmap_ptp_regs(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int bnxt_ptp_get_current_time(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
@ -627,11 +445,6 @@ int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bnxt_ptp_start(struct bnxt *bp)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bnxt_ptp_init(struct bnxt *bp)
|
int bnxt_ptp_init(struct bnxt *bp)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@
|
||||||
#define BNXT_PTP_H
|
#define BNXT_PTP_H
|
||||||
|
|
||||||
#define BNXT_MAX_PHC_DRIFT 31000000
|
#define BNXT_MAX_PHC_DRIFT 31000000
|
||||||
#define BNXT_LO_TIMER_MASK 0x0000ffffffffUL
|
|
||||||
#define BNXT_HI_TIMER_MASK 0xffff00000000UL
|
|
||||||
|
|
||||||
struct bnxt_ptp_cfg {
|
struct bnxt_ptp_cfg {
|
||||||
#ifdef HAVE_IEEE1588_SUPPORT
|
#ifdef HAVE_IEEE1588_SUPPORT
|
||||||
|
|
@ -20,10 +18,6 @@ struct bnxt_ptp_cfg {
|
||||||
struct ptp_clock *ptp_clock;
|
struct ptp_clock *ptp_clock;
|
||||||
struct cyclecounter cc;
|
struct cyclecounter cc;
|
||||||
struct timecounter tc;
|
struct timecounter tc;
|
||||||
struct sk_buff *tx_skb;
|
|
||||||
u64 current_time;
|
|
||||||
u64 old_time;
|
|
||||||
struct work_struct ptp_ts_task;
|
|
||||||
#endif
|
#endif
|
||||||
struct bnxt *bp;
|
struct bnxt *bp;
|
||||||
atomic_t tx_avail;
|
atomic_t tx_avail;
|
||||||
|
|
@ -66,16 +60,11 @@ struct bnxt_ptp_cfg {
|
||||||
u32 tx_mapped_regs[BNXT_PTP_TX_REGS];
|
u32 tx_mapped_regs[BNXT_PTP_TX_REGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
int bnxt_ptp_get_current_time(struct bnxt *bp);
|
|
||||||
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
|
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr);
|
||||||
int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
|
int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
|
||||||
int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb);
|
|
||||||
int bnxt_get_tx_ts(struct bnxt *bp, u64 *ts);
|
int bnxt_get_tx_ts(struct bnxt *bp, u64 *ts);
|
||||||
int bnxt_get_rx_ts(struct bnxt *bp, u64 *ts);
|
int bnxt_get_rx_ts(struct bnxt *bp, u64 *ts);
|
||||||
int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
|
|
||||||
int bnxt_ptp_start(struct bnxt *bp);
|
|
||||||
int bnxt_ptp_init(struct bnxt *bp);
|
int bnxt_ptp_init(struct bnxt *bp);
|
||||||
void bnxt_ptp_free(struct bnxt *bp);
|
void bnxt_ptp_free(struct bnxt *bp);
|
||||||
void bnxt_ptp_ts_task(struct work_struct *work);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,7 +27,6 @@
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_sriov.h"
|
#include "bnxt_sriov.h"
|
||||||
#include "bnxt_tc.h"
|
#include "bnxt_tc.h"
|
||||||
#include "bnxt_vfr.h"
|
#include "bnxt_vfr.h"
|
||||||
|
|
@ -58,7 +57,7 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev)
|
||||||
|
|
||||||
/* check if dev belongs to the same switch */
|
/* check if dev belongs to the same switch */
|
||||||
if (!netdev_port_same_parent_id(pf_bp->dev, dev)) {
|
if (!netdev_port_same_parent_id(pf_bp->dev, dev)) {
|
||||||
netdev_info(pf_bp->dev, "dev(ifindex=%d) not on same switch\n",
|
netdev_info(pf_bp->dev, "dev(ifindex=%d) not on same switch",
|
||||||
dev->ifindex);
|
dev->ifindex);
|
||||||
return BNXT_FID_INVALID;
|
return BNXT_FID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +80,7 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
|
||||||
struct net_device *dev = act->dev;
|
struct net_device *dev = act->dev;
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
netdev_info(bp->dev, "no dev in mirred action\n");
|
netdev_info(bp->dev, "no dev in mirred action");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +179,7 @@ static int bnxt_tc_parse_tunnel_set(struct bnxt *bp,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ip_tunnel_info_af(tun_info) != AF_INET) {
|
if (ip_tunnel_info_af(tun_info) != AF_INET) {
|
||||||
netdev_info(bp->dev, "only IPv4 tunnel-encap is supported\n");
|
netdev_info(bp->dev, "only IPv4 tunnel-encap is supported");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -356,8 +355,7 @@ bnxt_tc_parse_pedit(struct bnxt *bp, struct bnxt_tc_actions *actions,
|
||||||
|
|
||||||
static int bnxt_tc_parse_actions(struct bnxt *bp,
|
static int bnxt_tc_parse_actions(struct bnxt *bp,
|
||||||
struct bnxt_tc_actions *actions,
|
struct bnxt_tc_actions *actions,
|
||||||
struct flow_action *flow_action,
|
struct flow_action *flow_action)
|
||||||
struct netlink_ext_ack *extack)
|
|
||||||
{
|
{
|
||||||
/* Used to store the L2 rewrite mask for dmac (6 bytes) followed by
|
/* Used to store the L2 rewrite mask for dmac (6 bytes) followed by
|
||||||
* smac (6 bytes) if rewrite of both is specified, otherwise either
|
* smac (6 bytes) if rewrite of both is specified, otherwise either
|
||||||
|
|
@ -373,13 +371,10 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
if (!flow_action_has_entries(flow_action)) {
|
if (!flow_action_has_entries(flow_action)) {
|
||||||
netdev_info(bp->dev, "no actions\n");
|
netdev_info(bp->dev, "no actions");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flow_action_basic_hw_stats_check(flow_action, extack))
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
flow_action_for_each(i, act, flow_action) {
|
flow_action_for_each(i, act, flow_action) {
|
||||||
switch (act->id) {
|
switch (act->id) {
|
||||||
case FLOW_ACTION_DROP:
|
case FLOW_ACTION_DROP:
|
||||||
|
|
@ -665,7 +660,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
|
||||||
/* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
|
/* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
|
||||||
if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
|
if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
|
||||||
(dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
|
(dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
|
||||||
netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x\n",
|
netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x",
|
||||||
dissector->used_keys);
|
dissector->used_keys);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
@ -786,8 +781,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
|
||||||
flow->tun_mask.tp_src = match.mask->src;
|
flow->tun_mask.tp_src = match.mask->src;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action,
|
return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action);
|
||||||
tc_flow_cmd->common.extack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -955,20 +949,18 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
|
||||||
static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp,
|
static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp,
|
||||||
struct bnxt_tc_flow_node *flow_node)
|
struct bnxt_tc_flow_node *flow_node)
|
||||||
{
|
{
|
||||||
struct hwrm_cfa_flow_free_input *req;
|
struct hwrm_cfa_flow_free_input req = { 0 };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_FLOW_FREE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_FREE, -1, -1);
|
||||||
if (!rc) {
|
if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
|
||||||
if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE)
|
req.ext_flow_handle = flow_node->ext_flow_handle;
|
||||||
req->ext_flow_handle = flow_node->ext_flow_handle;
|
else
|
||||||
else
|
req.flow_handle = flow_node->flow_handle;
|
||||||
req->flow_handle = flow_node->flow_handle;
|
|
||||||
|
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc);
|
netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1042,22 +1034,20 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
|
||||||
struct bnxt_tc_actions *actions = &flow->actions;
|
struct bnxt_tc_actions *actions = &flow->actions;
|
||||||
struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask;
|
struct bnxt_tc_l3_key *l3_mask = &flow->l3_mask;
|
||||||
struct bnxt_tc_l3_key *l3_key = &flow->l3_key;
|
struct bnxt_tc_l3_key *l3_key = &flow->l3_key;
|
||||||
|
struct hwrm_cfa_flow_alloc_input req = { 0 };
|
||||||
struct hwrm_cfa_flow_alloc_output *resp;
|
struct hwrm_cfa_flow_alloc_output *resp;
|
||||||
struct hwrm_cfa_flow_alloc_input *req;
|
|
||||||
u16 flow_flags = 0, action_flags = 0;
|
u16 flow_flags = 0, action_flags = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_FLOW_ALLOC);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_ALLOC, -1, -1);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->src_fid = cpu_to_le16(flow->src_fid);
|
req.src_fid = cpu_to_le16(flow->src_fid);
|
||||||
req->ref_flow_handle = ref_flow_handle;
|
req.ref_flow_handle = ref_flow_handle;
|
||||||
|
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_L2_REWRITE) {
|
if (actions->flags & BNXT_TC_ACTION_FLAG_L2_REWRITE) {
|
||||||
memcpy(req->l2_rewrite_dmac, actions->l2_rewrite_dmac,
|
memcpy(req.l2_rewrite_dmac, actions->l2_rewrite_dmac,
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
memcpy(req->l2_rewrite_smac, actions->l2_rewrite_smac,
|
memcpy(req.l2_rewrite_smac, actions->l2_rewrite_smac,
|
||||||
ETH_ALEN);
|
ETH_ALEN);
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
||||||
|
|
@ -1072,71 +1062,71 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_SRC;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_SRC;
|
||||||
/* L3 source rewrite */
|
/* L3 source rewrite */
|
||||||
req->nat_ip_address[0] =
|
req.nat_ip_address[0] =
|
||||||
actions->nat.l3.ipv4.saddr.s_addr;
|
actions->nat.l3.ipv4.saddr.s_addr;
|
||||||
/* L4 source port */
|
/* L4 source port */
|
||||||
if (actions->nat.l4.ports.sport)
|
if (actions->nat.l4.ports.sport)
|
||||||
req->nat_port =
|
req.nat_port =
|
||||||
actions->nat.l4.ports.sport;
|
actions->nat.l4.ports.sport;
|
||||||
} else {
|
} else {
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_DEST;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_DEST;
|
||||||
/* L3 destination rewrite */
|
/* L3 destination rewrite */
|
||||||
req->nat_ip_address[0] =
|
req.nat_ip_address[0] =
|
||||||
actions->nat.l3.ipv4.daddr.s_addr;
|
actions->nat.l3.ipv4.daddr.s_addr;
|
||||||
/* L4 destination port */
|
/* L4 destination port */
|
||||||
if (actions->nat.l4.ports.dport)
|
if (actions->nat.l4.ports.dport)
|
||||||
req->nat_port =
|
req.nat_port =
|
||||||
actions->nat.l4.ports.dport;
|
actions->nat.l4.ports.dport;
|
||||||
}
|
}
|
||||||
netdev_dbg(bp->dev,
|
netdev_dbg(bp->dev,
|
||||||
"req.nat_ip_address: %pI4 src_xlate: %d req.nat_port: %x\n",
|
"req.nat_ip_address: %pI4 src_xlate: %d req.nat_port: %x\n",
|
||||||
req->nat_ip_address, actions->nat.src_xlate,
|
req.nat_ip_address, actions->nat.src_xlate,
|
||||||
req->nat_port);
|
req.nat_port);
|
||||||
} else {
|
} else {
|
||||||
if (actions->nat.src_xlate) {
|
if (actions->nat.src_xlate) {
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_SRC;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_SRC;
|
||||||
/* L3 source rewrite */
|
/* L3 source rewrite */
|
||||||
memcpy(req->nat_ip_address,
|
memcpy(req.nat_ip_address,
|
||||||
actions->nat.l3.ipv6.saddr.s6_addr32,
|
actions->nat.l3.ipv6.saddr.s6_addr32,
|
||||||
sizeof(req->nat_ip_address));
|
sizeof(req.nat_ip_address));
|
||||||
/* L4 source port */
|
/* L4 source port */
|
||||||
if (actions->nat.l4.ports.sport)
|
if (actions->nat.l4.ports.sport)
|
||||||
req->nat_port =
|
req.nat_port =
|
||||||
actions->nat.l4.ports.sport;
|
actions->nat.l4.ports.sport;
|
||||||
} else {
|
} else {
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_DEST;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_NAT_DEST;
|
||||||
/* L3 destination rewrite */
|
/* L3 destination rewrite */
|
||||||
memcpy(req->nat_ip_address,
|
memcpy(req.nat_ip_address,
|
||||||
actions->nat.l3.ipv6.daddr.s6_addr32,
|
actions->nat.l3.ipv6.daddr.s6_addr32,
|
||||||
sizeof(req->nat_ip_address));
|
sizeof(req.nat_ip_address));
|
||||||
/* L4 destination port */
|
/* L4 destination port */
|
||||||
if (actions->nat.l4.ports.dport)
|
if (actions->nat.l4.ports.dport)
|
||||||
req->nat_port =
|
req.nat_port =
|
||||||
actions->nat.l4.ports.dport;
|
actions->nat.l4.ports.dport;
|
||||||
}
|
}
|
||||||
netdev_dbg(bp->dev,
|
netdev_dbg(bp->dev,
|
||||||
"req.nat_ip_address: %pI6 src_xlate: %d req.nat_port: %x\n",
|
"req.nat_ip_address: %pI6 src_xlate: %d req.nat_port: %x\n",
|
||||||
req->nat_ip_address, actions->nat.src_xlate,
|
req.nat_ip_address, actions->nat.src_xlate,
|
||||||
req->nat_port);
|
req.nat_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP ||
|
if (actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP ||
|
||||||
actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) {
|
actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) {
|
||||||
req->tunnel_handle = tunnel_handle;
|
req.tunnel_handle = tunnel_handle;
|
||||||
flow_flags |= CFA_FLOW_ALLOC_REQ_FLAGS_TUNNEL;
|
flow_flags |= CFA_FLOW_ALLOC_REQ_FLAGS_TUNNEL;
|
||||||
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_TUNNEL;
|
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_TUNNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->ethertype = flow->l2_key.ether_type;
|
req.ethertype = flow->l2_key.ether_type;
|
||||||
req->ip_proto = flow->l4_key.ip_proto;
|
req.ip_proto = flow->l4_key.ip_proto;
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_ETH_ADDRS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_ETH_ADDRS) {
|
||||||
memcpy(req->dmac, flow->l2_key.dmac, ETH_ALEN);
|
memcpy(req.dmac, flow->l2_key.dmac, ETH_ALEN);
|
||||||
memcpy(req->smac, flow->l2_key.smac, ETH_ALEN);
|
memcpy(req.smac, flow->l2_key.smac, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flow->l2_key.num_vlans > 0) {
|
if (flow->l2_key.num_vlans > 0) {
|
||||||
|
|
@ -1145,7 +1135,7 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
|
||||||
* in outer_vlan_tci when num_vlans is 1 (which is
|
* in outer_vlan_tci when num_vlans is 1 (which is
|
||||||
* always the case in TC.)
|
* always the case in TC.)
|
||||||
*/
|
*/
|
||||||
req->outer_vlan_tci = flow->l2_key.inner_vlan_tci;
|
req.outer_vlan_tci = flow->l2_key.inner_vlan_tci;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If all IP and L4 fields are wildcarded then this is an L2 flow */
|
/* If all IP and L4 fields are wildcarded then this is an L2 flow */
|
||||||
|
|
@ -1158,67 +1148,68 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
|
||||||
CFA_FLOW_ALLOC_REQ_FLAGS_FLOWTYPE_IPV6;
|
CFA_FLOW_ALLOC_REQ_FLAGS_FLOWTYPE_IPV6;
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV4_ADDRS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV4_ADDRS) {
|
||||||
req->ip_dst[0] = l3_key->ipv4.daddr.s_addr;
|
req.ip_dst[0] = l3_key->ipv4.daddr.s_addr;
|
||||||
req->ip_dst_mask_len =
|
req.ip_dst_mask_len =
|
||||||
inet_mask_len(l3_mask->ipv4.daddr.s_addr);
|
inet_mask_len(l3_mask->ipv4.daddr.s_addr);
|
||||||
req->ip_src[0] = l3_key->ipv4.saddr.s_addr;
|
req.ip_src[0] = l3_key->ipv4.saddr.s_addr;
|
||||||
req->ip_src_mask_len =
|
req.ip_src_mask_len =
|
||||||
inet_mask_len(l3_mask->ipv4.saddr.s_addr);
|
inet_mask_len(l3_mask->ipv4.saddr.s_addr);
|
||||||
} else if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV6_ADDRS) {
|
} else if (flow->flags & BNXT_TC_FLOW_FLAGS_IPV6_ADDRS) {
|
||||||
memcpy(req->ip_dst, l3_key->ipv6.daddr.s6_addr32,
|
memcpy(req.ip_dst, l3_key->ipv6.daddr.s6_addr32,
|
||||||
sizeof(req->ip_dst));
|
sizeof(req.ip_dst));
|
||||||
req->ip_dst_mask_len =
|
req.ip_dst_mask_len =
|
||||||
ipv6_mask_len(&l3_mask->ipv6.daddr);
|
ipv6_mask_len(&l3_mask->ipv6.daddr);
|
||||||
memcpy(req->ip_src, l3_key->ipv6.saddr.s6_addr32,
|
memcpy(req.ip_src, l3_key->ipv6.saddr.s6_addr32,
|
||||||
sizeof(req->ip_src));
|
sizeof(req.ip_src));
|
||||||
req->ip_src_mask_len =
|
req.ip_src_mask_len =
|
||||||
ipv6_mask_len(&l3_mask->ipv6.saddr);
|
ipv6_mask_len(&l3_mask->ipv6.saddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) {
|
||||||
req->l4_src_port = flow->l4_key.ports.sport;
|
req.l4_src_port = flow->l4_key.ports.sport;
|
||||||
req->l4_src_port_mask = flow->l4_mask.ports.sport;
|
req.l4_src_port_mask = flow->l4_mask.ports.sport;
|
||||||
req->l4_dst_port = flow->l4_key.ports.dport;
|
req.l4_dst_port = flow->l4_key.ports.dport;
|
||||||
req->l4_dst_port_mask = flow->l4_mask.ports.dport;
|
req.l4_dst_port_mask = flow->l4_mask.ports.dport;
|
||||||
} else if (flow->flags & BNXT_TC_FLOW_FLAGS_ICMP) {
|
} else if (flow->flags & BNXT_TC_FLOW_FLAGS_ICMP) {
|
||||||
/* l4 ports serve as type/code when ip_proto is ICMP */
|
/* l4 ports serve as type/code when ip_proto is ICMP */
|
||||||
req->l4_src_port = htons(flow->l4_key.icmp.type);
|
req.l4_src_port = htons(flow->l4_key.icmp.type);
|
||||||
req->l4_src_port_mask = htons(flow->l4_mask.icmp.type);
|
req.l4_src_port_mask = htons(flow->l4_mask.icmp.type);
|
||||||
req->l4_dst_port = htons(flow->l4_key.icmp.code);
|
req.l4_dst_port = htons(flow->l4_key.icmp.code);
|
||||||
req->l4_dst_port_mask = htons(flow->l4_mask.icmp.code);
|
req.l4_dst_port_mask = htons(flow->l4_mask.icmp.code);
|
||||||
}
|
}
|
||||||
req->flags = cpu_to_le16(flow_flags);
|
req.flags = cpu_to_le16(flow_flags);
|
||||||
|
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_DROP) {
|
if (actions->flags & BNXT_TC_ACTION_FLAG_DROP) {
|
||||||
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_DROP;
|
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_DROP;
|
||||||
} else {
|
} else {
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_FWD) {
|
if (actions->flags & BNXT_TC_ACTION_FLAG_FWD) {
|
||||||
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_FWD;
|
action_flags |= CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_FWD;
|
||||||
req->dst_fid = cpu_to_le16(actions->dst_fid);
|
req.dst_fid = cpu_to_le16(actions->dst_fid);
|
||||||
}
|
}
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_PUSH_VLAN) {
|
if (actions->flags & BNXT_TC_ACTION_FLAG_PUSH_VLAN) {
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
||||||
req->l2_rewrite_vlan_tpid = actions->push_vlan_tpid;
|
req.l2_rewrite_vlan_tpid = actions->push_vlan_tpid;
|
||||||
req->l2_rewrite_vlan_tci = actions->push_vlan_tci;
|
req.l2_rewrite_vlan_tci = actions->push_vlan_tci;
|
||||||
memcpy(&req->l2_rewrite_dmac, &req->dmac, ETH_ALEN);
|
memcpy(&req.l2_rewrite_dmac, &req.dmac, ETH_ALEN);
|
||||||
memcpy(&req->l2_rewrite_smac, &req->smac, ETH_ALEN);
|
memcpy(&req.l2_rewrite_smac, &req.smac, ETH_ALEN);
|
||||||
}
|
}
|
||||||
if (actions->flags & BNXT_TC_ACTION_FLAG_POP_VLAN) {
|
if (actions->flags & BNXT_TC_ACTION_FLAG_POP_VLAN) {
|
||||||
action_flags |=
|
action_flags |=
|
||||||
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
CFA_FLOW_ALLOC_REQ_ACTION_FLAGS_L2_HEADER_REWRITE;
|
||||||
/* Rewrite config with tpid = 0 implies vlan pop */
|
/* Rewrite config with tpid = 0 implies vlan pop */
|
||||||
req->l2_rewrite_vlan_tpid = 0;
|
req.l2_rewrite_vlan_tpid = 0;
|
||||||
memcpy(&req->l2_rewrite_dmac, &req->dmac, ETH_ALEN);
|
memcpy(&req.l2_rewrite_dmac, &req.dmac, ETH_ALEN);
|
||||||
memcpy(&req->l2_rewrite_smac, &req->smac, ETH_ALEN);
|
memcpy(&req.l2_rewrite_smac, &req.smac, ETH_ALEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
req->action_flags = cpu_to_le16(action_flags);
|
req.action_flags = cpu_to_le16(action_flags);
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
|
resp = bnxt_get_hwrm_resp_addr(bp, &req);
|
||||||
/* CFA_FLOW_ALLOC response interpretation:
|
/* CFA_FLOW_ALLOC response interpretation:
|
||||||
* fw with fw with
|
* fw with fw with
|
||||||
* 16-bit 64-bit
|
* 16-bit 64-bit
|
||||||
|
|
@ -1234,7 +1225,7 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
|
||||||
flow_node->flow_id = resp->flow_id;
|
flow_node->flow_id = resp->flow_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1244,69 +1235,67 @@ static int hwrm_cfa_decap_filter_alloc(struct bnxt *bp,
|
||||||
__le32 ref_decap_handle,
|
__le32 ref_decap_handle,
|
||||||
__le32 *decap_filter_handle)
|
__le32 *decap_filter_handle)
|
||||||
{
|
{
|
||||||
|
struct hwrm_cfa_decap_filter_alloc_input req = { 0 };
|
||||||
struct hwrm_cfa_decap_filter_alloc_output *resp;
|
struct hwrm_cfa_decap_filter_alloc_output *resp;
|
||||||
struct ip_tunnel_key *tun_key = &flow->tun_key;
|
struct ip_tunnel_key *tun_key = &flow->tun_key;
|
||||||
struct hwrm_cfa_decap_filter_alloc_input *req;
|
|
||||||
u32 enables = 0;
|
u32 enables = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_DECAP_FILTER_ALLOC);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_DECAP_FILTER_ALLOC, -1, -1);
|
||||||
if (rc)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
req->flags = cpu_to_le32(CFA_DECAP_FILTER_ALLOC_REQ_FLAGS_OVS_TUNNEL);
|
req.flags = cpu_to_le32(CFA_DECAP_FILTER_ALLOC_REQ_FLAGS_OVS_TUNNEL);
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE |
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE |
|
||||||
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL;
|
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL;
|
||||||
req->tunnel_type = CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
|
req.tunnel_type = CFA_DECAP_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
|
||||||
req->ip_protocol = CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP;
|
req.ip_protocol = CFA_DECAP_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP;
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ID) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ID) {
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_ID;
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_TUNNEL_ID;
|
||||||
/* tunnel_id is wrongly defined in hsi defn. as __le32 */
|
/* tunnel_id is wrongly defined in hsi defn. as __le32 */
|
||||||
req->tunnel_id = tunnel_id_to_key32(tun_key->tun_id);
|
req.tunnel_id = tunnel_id_to_key32(tun_key->tun_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS) {
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR;
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR;
|
||||||
ether_addr_copy(req->dst_macaddr, l2_info->dmac);
|
ether_addr_copy(req.dst_macaddr, l2_info->dmac);
|
||||||
}
|
}
|
||||||
if (l2_info->num_vlans) {
|
if (l2_info->num_vlans) {
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_T_IVLAN_VID;
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_T_IVLAN_VID;
|
||||||
req->t_ivlan_vid = l2_info->inner_vlan_tci;
|
req.t_ivlan_vid = l2_info->inner_vlan_tci;
|
||||||
}
|
}
|
||||||
|
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE;
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE;
|
||||||
req->ethertype = htons(ETH_P_IP);
|
req.ethertype = htons(ETH_P_IP);
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS) {
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR |
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR |
|
||||||
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR |
|
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR |
|
||||||
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE;
|
CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE;
|
||||||
req->ip_addr_type =
|
req.ip_addr_type = CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4;
|
||||||
CFA_DECAP_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4;
|
req.dst_ipaddr[0] = tun_key->u.ipv4.dst;
|
||||||
req->dst_ipaddr[0] = tun_key->u.ipv4.dst;
|
req.src_ipaddr[0] = tun_key->u.ipv4.src;
|
||||||
req->src_ipaddr[0] = tun_key->u.ipv4.src;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_PORTS) {
|
if (flow->flags & BNXT_TC_FLOW_FLAGS_TUNL_PORTS) {
|
||||||
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_PORT;
|
enables |= CFA_DECAP_FILTER_ALLOC_REQ_ENABLES_DST_PORT;
|
||||||
req->dst_port = tun_key->tp_dst;
|
req.dst_port = tun_key->tp_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eventhough the decap_handle returned by hwrm_cfa_decap_filter_alloc
|
/* Eventhough the decap_handle returned by hwrm_cfa_decap_filter_alloc
|
||||||
* is defined as __le32, l2_ctxt_ref_id is defined in HSI as __le16.
|
* is defined as __le32, l2_ctxt_ref_id is defined in HSI as __le16.
|
||||||
*/
|
*/
|
||||||
req->l2_ctxt_ref_id = (__force __le16)ref_decap_handle;
|
req.l2_ctxt_ref_id = (__force __le16)ref_decap_handle;
|
||||||
req->enables = cpu_to_le32(enables);
|
req.enables = cpu_to_le32(enables);
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc)
|
if (!rc) {
|
||||||
|
resp = bnxt_get_hwrm_resp_addr(bp, &req);
|
||||||
*decap_filter_handle = resp->decap_filter_id;
|
*decap_filter_handle = resp->decap_filter_id;
|
||||||
hwrm_req_drop(bp, req);
|
} else {
|
||||||
exit:
|
netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
|
||||||
if (rc)
|
}
|
||||||
netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1314,16 +1303,15 @@ exit:
|
||||||
static int hwrm_cfa_decap_filter_free(struct bnxt *bp,
|
static int hwrm_cfa_decap_filter_free(struct bnxt *bp,
|
||||||
__le32 decap_filter_handle)
|
__le32 decap_filter_handle)
|
||||||
{
|
{
|
||||||
struct hwrm_cfa_decap_filter_free_input *req;
|
struct hwrm_cfa_decap_filter_free_input req = { 0 };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_DECAP_FILTER_FREE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_DECAP_FILTER_FREE, -1, -1);
|
||||||
if (!rc) {
|
req.decap_filter_id = decap_filter_handle;
|
||||||
req->decap_filter_id = decap_filter_handle;
|
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc);
|
netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1333,20 +1321,17 @@ static int hwrm_cfa_encap_record_alloc(struct bnxt *bp,
|
||||||
struct bnxt_tc_l2_key *l2_info,
|
struct bnxt_tc_l2_key *l2_info,
|
||||||
__le32 *encap_record_handle)
|
__le32 *encap_record_handle)
|
||||||
{
|
{
|
||||||
|
struct hwrm_cfa_encap_record_alloc_input req = { 0 };
|
||||||
struct hwrm_cfa_encap_record_alloc_output *resp;
|
struct hwrm_cfa_encap_record_alloc_output *resp;
|
||||||
struct hwrm_cfa_encap_record_alloc_input *req;
|
struct hwrm_cfa_encap_data_vxlan *encap =
|
||||||
struct hwrm_cfa_encap_data_vxlan *encap;
|
(struct hwrm_cfa_encap_data_vxlan *)&req.encap_data;
|
||||||
struct hwrm_vxlan_ipv4_hdr *encap_ipv4;
|
struct hwrm_vxlan_ipv4_hdr *encap_ipv4 =
|
||||||
|
(struct hwrm_vxlan_ipv4_hdr *)encap->l3;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_ENCAP_RECORD_ALLOC);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_ENCAP_RECORD_ALLOC, -1, -1);
|
||||||
if (rc)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
encap = (struct hwrm_cfa_encap_data_vxlan *)&req->encap_data;
|
req.encap_type = CFA_ENCAP_RECORD_ALLOC_REQ_ENCAP_TYPE_VXLAN;
|
||||||
encap_ipv4 = (struct hwrm_vxlan_ipv4_hdr *)encap->l3;
|
|
||||||
|
|
||||||
req->encap_type = CFA_ENCAP_RECORD_ALLOC_REQ_ENCAP_TYPE_VXLAN;
|
|
||||||
|
|
||||||
ether_addr_copy(encap->dst_mac_addr, l2_info->dmac);
|
ether_addr_copy(encap->dst_mac_addr, l2_info->dmac);
|
||||||
ether_addr_copy(encap->src_mac_addr, l2_info->smac);
|
ether_addr_copy(encap->src_mac_addr, l2_info->smac);
|
||||||
|
|
@ -1367,14 +1352,15 @@ static int hwrm_cfa_encap_record_alloc(struct bnxt *bp,
|
||||||
encap->dst_port = encap_key->tp_dst;
|
encap->dst_port = encap_key->tp_dst;
|
||||||
encap->vni = tunnel_id_to_key32(encap_key->tun_id);
|
encap->vni = tunnel_id_to_key32(encap_key->tun_id);
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc)
|
if (!rc) {
|
||||||
|
resp = bnxt_get_hwrm_resp_addr(bp, &req);
|
||||||
*encap_record_handle = resp->encap_record_id;
|
*encap_record_handle = resp->encap_record_id;
|
||||||
hwrm_req_drop(bp, req);
|
} else {
|
||||||
exit:
|
netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
|
||||||
if (rc)
|
}
|
||||||
netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1382,16 +1368,15 @@ exit:
|
||||||
static int hwrm_cfa_encap_record_free(struct bnxt *bp,
|
static int hwrm_cfa_encap_record_free(struct bnxt *bp,
|
||||||
__le32 encap_record_handle)
|
__le32 encap_record_handle)
|
||||||
{
|
{
|
||||||
struct hwrm_cfa_encap_record_free_input *req;
|
struct hwrm_cfa_encap_record_free_input req = { 0 };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_ENCAP_RECORD_FREE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_ENCAP_RECORD_FREE, -1, -1);
|
||||||
if (!rc) {
|
req.encap_record_id = encap_record_handle;
|
||||||
req->encap_record_id = encap_record_handle;
|
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc);
|
netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -1410,7 +1395,7 @@ static int bnxt_tc_put_l2_node(struct bnxt *bp,
|
||||||
tc_info->l2_ht_params);
|
tc_info->l2_ht_params);
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_err(bp->dev,
|
netdev_err(bp->dev,
|
||||||
"Error: %s: rhashtable_remove_fast: %d\n",
|
"Error: %s: rhashtable_remove_fast: %d",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
kfree_rcu(l2_node, rcu);
|
kfree_rcu(l2_node, rcu);
|
||||||
}
|
}
|
||||||
|
|
@ -1439,7 +1424,7 @@ bnxt_tc_get_l2_node(struct bnxt *bp, struct rhashtable *l2_table,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
kfree_rcu(l2_node, rcu);
|
kfree_rcu(l2_node, rcu);
|
||||||
netdev_err(bp->dev,
|
netdev_err(bp->dev,
|
||||||
"Error: %s: rhashtable_insert_fast: %d\n",
|
"Error: %s: rhashtable_insert_fast: %d",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1498,7 +1483,7 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow)
|
||||||
if ((flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) &&
|
if ((flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) &&
|
||||||
(flow->l4_key.ip_proto != IPPROTO_TCP &&
|
(flow->l4_key.ip_proto != IPPROTO_TCP &&
|
||||||
flow->l4_key.ip_proto != IPPROTO_UDP)) {
|
flow->l4_key.ip_proto != IPPROTO_UDP)) {
|
||||||
netdev_info(bp->dev, "Cannot offload non-TCP/UDP (%d) ports\n",
|
netdev_info(bp->dev, "Cannot offload non-TCP/UDP (%d) ports",
|
||||||
flow->l4_key.ip_proto);
|
flow->l4_key.ip_proto);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1563,7 +1548,7 @@ static int bnxt_tc_put_tunnel_node(struct bnxt *bp,
|
||||||
rc = rhashtable_remove_fast(tunnel_table, &tunnel_node->node,
|
rc = rhashtable_remove_fast(tunnel_table, &tunnel_node->node,
|
||||||
*ht_params);
|
*ht_params);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netdev_err(bp->dev, "rhashtable_remove_fast rc=%d\n", rc);
|
netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
kfree_rcu(tunnel_node, rcu);
|
kfree_rcu(tunnel_node, rcu);
|
||||||
|
|
@ -1605,7 +1590,7 @@ bnxt_tc_get_tunnel_node(struct bnxt *bp, struct rhashtable *tunnel_table,
|
||||||
tunnel_node->refcount++;
|
tunnel_node->refcount++;
|
||||||
return tunnel_node;
|
return tunnel_node;
|
||||||
err:
|
err:
|
||||||
netdev_info(bp->dev, "error rc=%d\n", rc);
|
netdev_info(bp->dev, "error rc=%d", rc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1663,7 +1648,7 @@ static void bnxt_tc_put_decap_l2_node(struct bnxt *bp,
|
||||||
&decap_l2_node->node,
|
&decap_l2_node->node,
|
||||||
tc_info->decap_l2_ht_params);
|
tc_info->decap_l2_ht_params);
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_err(bp->dev, "rhashtable_remove_fast rc=%d\n", rc);
|
netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc);
|
||||||
kfree_rcu(decap_l2_node, rcu);
|
kfree_rcu(decap_l2_node, rcu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1703,7 +1688,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
|
||||||
|
|
||||||
rt = ip_route_output_key(dev_net(real_dst_dev), &flow);
|
rt = ip_route_output_key(dev_net(real_dst_dev), &flow);
|
||||||
if (IS_ERR(rt)) {
|
if (IS_ERR(rt)) {
|
||||||
netdev_info(bp->dev, "no route to %pI4b\n", &flow.daddr);
|
netdev_info(bp->dev, "no route to %pI4b", &flow.daddr);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1717,7 +1702,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
|
||||||
|
|
||||||
if (vlan->real_dev != real_dst_dev) {
|
if (vlan->real_dev != real_dst_dev) {
|
||||||
netdev_info(bp->dev,
|
netdev_info(bp->dev,
|
||||||
"dst_dev(%s) doesn't use PF-if(%s)\n",
|
"dst_dev(%s) doesn't use PF-if(%s)",
|
||||||
netdev_name(dst_dev),
|
netdev_name(dst_dev),
|
||||||
netdev_name(real_dst_dev));
|
netdev_name(real_dst_dev));
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
|
|
@ -1729,7 +1714,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
|
||||||
#endif
|
#endif
|
||||||
} else if (dst_dev != real_dst_dev) {
|
} else if (dst_dev != real_dst_dev) {
|
||||||
netdev_info(bp->dev,
|
netdev_info(bp->dev,
|
||||||
"dst_dev(%s) for %pI4b is not PF-if(%s)\n",
|
"dst_dev(%s) for %pI4b is not PF-if(%s)",
|
||||||
netdev_name(dst_dev), &flow.daddr,
|
netdev_name(dst_dev), &flow.daddr,
|
||||||
netdev_name(real_dst_dev));
|
netdev_name(real_dst_dev));
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
|
|
@ -1738,7 +1723,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
|
||||||
|
|
||||||
nbr = dst_neigh_lookup(&rt->dst, &flow.daddr);
|
nbr = dst_neigh_lookup(&rt->dst, &flow.daddr);
|
||||||
if (!nbr) {
|
if (!nbr) {
|
||||||
netdev_info(bp->dev, "can't lookup neighbor for %pI4b\n",
|
netdev_info(bp->dev, "can't lookup neighbor for %pI4b",
|
||||||
&flow.daddr);
|
&flow.daddr);
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
goto put_rt;
|
goto put_rt;
|
||||||
|
|
@ -1950,7 +1935,7 @@ static int __bnxt_tc_del_flow(struct bnxt *bp,
|
||||||
rc = rhashtable_remove_fast(&tc_info->flow_table, &flow_node->node,
|
rc = rhashtable_remove_fast(&tc_info->flow_table, &flow_node->node,
|
||||||
tc_info->flow_ht_params);
|
tc_info->flow_ht_params);
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_err(bp->dev, "Error: %s: rhashtable_remove_fast rc=%d\n",
|
netdev_err(bp->dev, "Error: %s: rhashtable_remove_fast rc=%d",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
|
|
||||||
kfree_rcu(flow_node, rcu);
|
kfree_rcu(flow_node, rcu);
|
||||||
|
|
@ -2086,7 +2071,7 @@ unlock:
|
||||||
free_node:
|
free_node:
|
||||||
kfree_rcu(new_node, rcu);
|
kfree_rcu(new_node, rcu);
|
||||||
done:
|
done:
|
||||||
netdev_err(bp->dev, "Error: %s: cookie=0x%lx error=%d\n",
|
netdev_err(bp->dev, "Error: %s: cookie=0x%lx error=%d",
|
||||||
__func__, tc_flow_cmd->cookie, rc);
|
__func__, tc_flow_cmd->cookie, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -2154,7 +2139,7 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
|
||||||
|
|
||||||
#ifdef HAVE_FLOW_OFFLOAD_H
|
#ifdef HAVE_FLOW_OFFLOAD_H
|
||||||
flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets,
|
flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets,
|
||||||
lastused, FLOW_ACTION_HW_STATS_DELAYED);
|
lastused);
|
||||||
#else
|
#else
|
||||||
tcf_exts_stats_update(tc_flow_cmd->exts, stats.bytes, stats.packets,
|
tcf_exts_stats_update(tc_flow_cmd->exts, stats.bytes, stats.packets,
|
||||||
lastused);
|
lastused);
|
||||||
|
|
@ -2192,20 +2177,14 @@ static int
|
||||||
bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
|
bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
|
||||||
struct bnxt_tc_stats_batch stats_batch[])
|
struct bnxt_tc_stats_batch stats_batch[])
|
||||||
{
|
{
|
||||||
|
struct hwrm_cfa_flow_stats_input req = { 0 };
|
||||||
struct hwrm_cfa_flow_stats_output *resp;
|
struct hwrm_cfa_flow_stats_output *resp;
|
||||||
struct hwrm_cfa_flow_stats_input *req;
|
__le16 *req_flow_handles = &req.flow_handle_0;
|
||||||
__le16 *req_flow_handles;
|
__le32 *req_flow_ids = &req.flow_id_0;
|
||||||
__le32 *req_flow_ids;
|
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_FLOW_STATS);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_FLOW_STATS, -1, -1);
|
||||||
if (rc)
|
req.num_flows = cpu_to_le16(num_flows);
|
||||||
goto exit;
|
|
||||||
|
|
||||||
req_flow_handles = &req->flow_handle_0;
|
|
||||||
req_flow_ids = &req->flow_id_0;
|
|
||||||
|
|
||||||
req->num_flows = cpu_to_le16(num_flows);
|
|
||||||
for (i = 0; i < num_flows; i++) {
|
for (i = 0; i < num_flows; i++) {
|
||||||
struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node;
|
struct bnxt_tc_flow_node *flow_node = stats_batch[i].flow_node;
|
||||||
|
|
||||||
|
|
@ -2213,12 +2192,13 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
|
||||||
&req_flow_handles[i], &req_flow_ids[i]);
|
&req_flow_handles[i], &req_flow_ids[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
__le64 *resp_packets;
|
__le64 *resp_packets;
|
||||||
__le64 *resp_bytes;
|
__le64 *resp_bytes;
|
||||||
|
|
||||||
|
resp = bnxt_get_hwrm_resp_addr(bp, &req);
|
||||||
resp_packets = &resp->packet_0;
|
resp_packets = &resp->packet_0;
|
||||||
resp_bytes = &resp->byte_0;
|
resp_bytes = &resp->byte_0;
|
||||||
|
|
||||||
|
|
@ -2228,11 +2208,10 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
|
||||||
stats_batch[i].hw_stats.bytes =
|
stats_batch[i].hw_stats.bytes =
|
||||||
le64_to_cpu(resp_bytes[i]);
|
le64_to_cpu(resp_bytes[i]);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
netdev_info(bp->dev, "error rc=%d", rc);
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
exit:
|
|
||||||
if (rc)
|
|
||||||
netdev_info(bp->dev, "error rc=%d\n", rc);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -2538,7 +2517,7 @@ static int bnxt_tc_indr_block_event(struct notifier_block *nb,
|
||||||
bp);
|
bp);
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_info(bp->dev,
|
netdev_info(bp->dev,
|
||||||
"Failed to register indirect blk: dev: %s\n",
|
"Failed to register indirect blk: dev: %s",
|
||||||
netdev->name);
|
netdev->name);
|
||||||
break;
|
break;
|
||||||
case NETDEV_UNREGISTER:
|
case NETDEV_UNREGISTER:
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_ulp.h"
|
#include "bnxt_ulp.h"
|
||||||
|
|
||||||
static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id,
|
static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id,
|
||||||
|
|
@ -108,13 +107,9 @@ static void bnxt_fill_msix_vecs(struct bnxt *bp, struct bnxt_msix_entry *ent)
|
||||||
ent[i].vector = bp->irq_tbl[idx + i].vector;
|
ent[i].vector = bp->irq_tbl[idx + i].vector;
|
||||||
ent[i].ring_idx = idx + i;
|
ent[i].ring_idx = idx + i;
|
||||||
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
||||||
if (bp->flags & BNXT_FLAG_CHIP_SR2) {
|
ent[i].db_offset = DB_PF_OFFSET_P5;
|
||||||
ent[i].db_offset = bp->legacy_db_size;
|
if (BNXT_VF(bp))
|
||||||
} else {
|
ent[i].db_offset = DB_VF_OFFSET_P5;
|
||||||
ent[i].db_offset = DB_PF_OFFSET_P5;
|
|
||||||
if (BNXT_VF(bp))
|
|
||||||
ent[i].db_offset = DB_VF_OFFSET_P5;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ent[i].db_offset = (idx + i) * 0x80;
|
ent[i].db_offset = (idx + i) * 0x80;
|
||||||
}
|
}
|
||||||
|
|
@ -240,25 +235,19 @@ static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id,
|
||||||
{
|
{
|
||||||
struct net_device *dev = edev->net;
|
struct net_device *dev = edev->net;
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
struct output *resp;
|
|
||||||
struct input *req;
|
struct input *req;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ((ulp_id != BNXT_ROCE_ULP) && bp->fw_reset_state)
|
if ((ulp_id != BNXT_ROCE_ULP) && bp->fw_reset_state)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, 0 /* don't care */);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
if (rc)
|
req = fw_msg->msg;
|
||||||
return rc;
|
req->resp_addr = cpu_to_le64(bp->hwrm_cmd_resp_dma_addr);
|
||||||
|
rc = _hwrm_send_message(bp, fw_msg->msg, fw_msg->msg_len,
|
||||||
rc = hwrm_req_replace(bp, req, fw_msg->msg, fw_msg->msg_len);
|
fw_msg->timeout);
|
||||||
if (rc)
|
if (rc != -EBUSY && rc != -E2BIG) {
|
||||||
return rc;
|
struct output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
|
|
||||||
hwrm_req_timeout(bp, req, fw_msg->timeout);
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
|
||||||
if (!rc || rc == -EAGAIN) {
|
|
||||||
u32 len = le16_to_cpu(resp->resp_len);
|
u32 len = le16_to_cpu(resp->resp_len);
|
||||||
|
|
||||||
if (fw_msg->resp_max_len < len)
|
if (fw_msg->resp_max_len < len)
|
||||||
|
|
@ -266,7 +255,7 @@ static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id,
|
||||||
|
|
||||||
memcpy(fw_msg->resp, resp, len);
|
memcpy(fw_msg->resp, resp, len);
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,10 +471,6 @@ struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev)
|
||||||
struct bnxt *bp = netdev_priv(dev);
|
struct bnxt *bp = netdev_priv(dev);
|
||||||
struct bnxt_en_dev *edev;
|
struct bnxt_en_dev *edev;
|
||||||
|
|
||||||
#if (BITS_PER_LONG == 64)
|
|
||||||
BUILD_BUG_ON(offsetof(struct bnxt, reserved_ulp_kabi_0) != 0x40);
|
|
||||||
BUILD_BUG_ON(offsetof(struct bnxt, reserved_ulp_kabi_1) != 0x80);
|
|
||||||
#endif
|
|
||||||
edev = bp->edev;
|
edev = bp->edev;
|
||||||
if (!edev) {
|
if (!edev) {
|
||||||
edev = kzalloc(sizeof(*edev), GFP_KERNEL);
|
edev = kzalloc(sizeof(*edev), GFP_KERNEL);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
#include "bnxt_compat.h"
|
#include "bnxt_compat.h"
|
||||||
#include "bnxt_hsi.h"
|
#include "bnxt_hsi.h"
|
||||||
#include "bnxt.h"
|
#include "bnxt.h"
|
||||||
#include "bnxt_hwrm.h"
|
|
||||||
#include "bnxt_vfr.h"
|
#include "bnxt_vfr.h"
|
||||||
#include "bnxt_devlink.h"
|
#include "bnxt_devlink.h"
|
||||||
#include "bnxt_tc.h"
|
#include "bnxt_tc.h"
|
||||||
|
|
@ -31,60 +30,57 @@
|
||||||
static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx,
|
static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx,
|
||||||
u16 *tx_cfa_action, u16 *rx_cfa_code)
|
u16 *tx_cfa_action, u16 *rx_cfa_code)
|
||||||
{
|
{
|
||||||
struct hwrm_cfa_vfr_alloc_output *resp;
|
struct hwrm_cfa_vfr_alloc_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_cfa_vfr_alloc_input *req;
|
struct hwrm_cfa_vfr_alloc_input req = { 0 };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_ALLOC);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_VFR_ALLOC, -1, -1);
|
||||||
if (!rc) {
|
req.vf_id = cpu_to_le16(vf_idx);
|
||||||
req->vf_id = cpu_to_le16(vf_idx);
|
sprintf(req.vfr_name, "vfr%d", vf_idx);
|
||||||
sprintf(req->vfr_name, "vfr%d", vf_idx);
|
|
||||||
|
|
||||||
resp = hwrm_req_hold(bp, req);
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
*tx_cfa_action = le16_to_cpu(resp->tx_cfa_action);
|
*tx_cfa_action = le16_to_cpu(resp->tx_cfa_action);
|
||||||
*rx_cfa_code = le16_to_cpu(resp->rx_cfa_code);
|
*rx_cfa_code = le16_to_cpu(resp->rx_cfa_code);
|
||||||
netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
|
netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
|
||||||
*tx_cfa_action, *rx_cfa_code);
|
*tx_cfa_action, *rx_cfa_code);
|
||||||
}
|
} else {
|
||||||
hwrm_req_drop(bp, req);
|
netdev_info(bp->dev, "%s error rc=%d", __func__, rc);
|
||||||
}
|
}
|
||||||
if (rc)
|
|
||||||
netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
|
static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
|
||||||
{
|
{
|
||||||
struct hwrm_cfa_vfr_free_input *req;
|
struct hwrm_cfa_vfr_free_input req = { 0 };
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_FREE);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_VFR_FREE, -1, -1);
|
||||||
if (!rc) {
|
sprintf(req.vfr_name, "vfr%d", vf_idx);
|
||||||
sprintf(req->vfr_name, "vfr%d", vf_idx);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
}
|
|
||||||
if (rc)
|
if (rc)
|
||||||
netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
|
netdev_info(bp->dev, "%s error rc=%d", __func__, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
|
static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
|
||||||
u16 *max_mtu)
|
u16 *max_mtu)
|
||||||
{
|
{
|
||||||
struct hwrm_func_qcfg_output *resp;
|
struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
||||||
struct hwrm_func_qcfg_input *req;
|
struct hwrm_func_qcfg_input req = {0};
|
||||||
u16 mtu;
|
u16 mtu;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = hwrm_req_init(bp, req, HWRM_FUNC_QCFG);
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1);
|
||||||
if (rc)
|
req.fid = bp->pf.vf[vf_rep->vf_idx].fw_fid;
|
||||||
return rc;
|
|
||||||
|
|
||||||
req->fid = bp->pf.vf[vf_rep->vf_idx].fw_fid;
|
mutex_lock(&bp->hwrm_cmd_lock);
|
||||||
resp = hwrm_req_hold(bp, req);
|
|
||||||
rc = hwrm_req_send(bp, req);
|
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
mtu = le16_to_cpu(resp->max_mtu_configured);
|
mtu = le16_to_cpu(resp->max_mtu_configured);
|
||||||
if (!mtu)
|
if (!mtu)
|
||||||
|
|
@ -92,8 +88,7 @@ static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
|
||||||
else
|
else
|
||||||
*max_mtu = mtu;
|
*max_mtu = mtu;
|
||||||
}
|
}
|
||||||
hwrm_req_drop(bp, req);
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -624,7 +619,7 @@ static int bnxt_vf_reps_create(struct bnxt *bp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
|
netdev_info(bp->dev, "%s error=%d", __func__, rc);
|
||||||
kfree(cfa_code_map);
|
kfree(cfa_code_map);
|
||||||
__bnxt_vf_reps_destroy(bp);
|
__bnxt_vf_reps_destroy(bp);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -651,7 +646,7 @@ int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode)
|
||||||
|
|
||||||
mutex_lock(&bp->sriov_lock);
|
mutex_lock(&bp->sriov_lock);
|
||||||
if (bp->eswitch_mode == mode) {
|
if (bp->eswitch_mode == mode) {
|
||||||
netdev_info(bp->dev, "already in %s eswitch mode\n",
|
netdev_info(bp->dev, "already in %s eswitch mode",
|
||||||
mode == DEVLINK_ESWITCH_MODE_LEGACY ?
|
mode == DEVLINK_ESWITCH_MODE_LEGACY ?
|
||||||
"legacy" : "switchdev");
|
"legacy" : "switchdev");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
|
|
@ -671,7 +666,7 @@ int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_num_vf(bp->pdev) == 0) {
|
if (pci_num_vf(bp->pdev) == 0) {
|
||||||
netdev_info(bp->dev, "Enable VFs before setting switchdev mode\n");
|
netdev_info(bp->dev, "Enable VFs before setting switchdev mode");
|
||||||
rc = -EPERM;
|
rc = -EPERM;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,6 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||||
xdp.data_end = *data_ptr + *len;
|
xdp.data_end = *data_ptr + *len;
|
||||||
#ifdef HAVE_XDP_RXQ_INFO
|
#ifdef HAVE_XDP_RXQ_INFO
|
||||||
xdp.rxq = &rxr->xdp_rxq;
|
xdp.rxq = &rxr->xdp_rxq;
|
||||||
#endif
|
|
||||||
#ifdef HAVE_XDP_FRAME_SZ
|
|
||||||
xdp.frame_sz = PAGE_SIZE; /* BNXT_RX_PAGE_MODE(bp) when XDP enabled */
|
|
||||||
#endif
|
#endif
|
||||||
orig_data = xdp.data;
|
orig_data = xdp.data;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
|
set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
|
||||||
device_add_disk(dev, disk, NULL);
|
device_add_disk(dev, disk);
|
||||||
revalidate_disk(disk);
|
revalidate_disk(disk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1553,7 +1553,7 @@ static int btt_blk_init(struct btt *btt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
|
set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
|
||||||
device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL);
|
device_add_disk(&btt->nd_btt->dev, btt->btt_disk);
|
||||||
btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
|
btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
|
||||||
revalidate_disk(btt->btt_disk);
|
revalidate_disk(btt->btt_disk);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,7 @@ static int pmem_attach_disk(struct device *dev,
|
||||||
gendev = disk_to_dev(disk);
|
gendev = disk_to_dev(disk);
|
||||||
gendev->groups = pmem_attribute_groups;
|
gendev->groups = pmem_attribute_groups;
|
||||||
|
|
||||||
device_add_disk(dev, disk, NULL);
|
device_add_disk(dev, disk);
|
||||||
if (devm_add_action_or_reset(dev, pmem_release_disk, pmem))
|
if (devm_add_action_or_reset(dev, pmem_release_disk, pmem))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2165,14 +2165,6 @@ static const struct attribute_group nvme_ns_attr_group = {
|
||||||
.is_visible = nvme_ns_attrs_are_visible,
|
.is_visible = nvme_ns_attrs_are_visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct attribute_group *nvme_ns_id_attr_groups[] = {
|
|
||||||
&nvme_ns_attr_group,
|
|
||||||
#ifdef CONFIG_NVM
|
|
||||||
&nvme_nvm_attr_group,
|
|
||||||
#endif
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define nvme_show_str_function(field) \
|
#define nvme_show_str_function(field) \
|
||||||
static ssize_t field##_show(struct device *dev, \
|
static ssize_t field##_show(struct device *dev, \
|
||||||
struct device_attribute *attr, char *buf) \
|
struct device_attribute *attr, char *buf) \
|
||||||
|
|
@ -2423,7 +2415,14 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
|
||||||
|
|
||||||
kfree(id);
|
kfree(id);
|
||||||
|
|
||||||
device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups);
|
device_add_disk(ctrl->device, ns->disk);
|
||||||
|
if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
|
||||||
|
&nvme_ns_attr_group))
|
||||||
|
pr_warn("%s: failed to create sysfs group for identification\n",
|
||||||
|
ns->disk->disk_name);
|
||||||
|
if (ns->ndev && nvme_nvm_register_sysfs(ns))
|
||||||
|
pr_warn("%s: failed to register lightnvm sysfs group for identification\n",
|
||||||
|
ns->disk->disk_name);
|
||||||
return;
|
return;
|
||||||
out_free_id:
|
out_free_id:
|
||||||
kfree(id);
|
kfree(id);
|
||||||
|
|
@ -2443,6 +2442,10 @@ static void nvme_ns_remove(struct nvme_ns *ns)
|
||||||
if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
|
if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
|
||||||
if (blk_get_integrity(ns->disk))
|
if (blk_get_integrity(ns->disk))
|
||||||
blk_integrity_unregister(ns->disk);
|
blk_integrity_unregister(ns->disk);
|
||||||
|
sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
|
||||||
|
&nvme_ns_attr_group);
|
||||||
|
if (ns->ndev)
|
||||||
|
nvme_nvm_unregister_sysfs(ns);
|
||||||
del_gendisk(ns->disk);
|
del_gendisk(ns->disk);
|
||||||
blk_cleanup_queue(ns->queue);
|
blk_cleanup_queue(ns->queue);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -939,27 +939,19 @@ static struct attribute *nvm_dev_attrs[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static umode_t nvm_dev_attrs_visible(struct kobject *kobj,
|
static const struct attribute_group nvm_dev_attr_group = {
|
||||||
struct attribute *attr, int index)
|
.name = "lightnvm",
|
||||||
|
.attrs = nvm_dev_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
int nvme_nvm_register_sysfs(struct nvme_ns *ns)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
|
||||||
struct gendisk *disk = dev_to_disk(dev);
|
&nvm_dev_attr_group);
|
||||||
struct nvme_ns *ns = disk->private_data;
|
|
||||||
struct nvm_dev *ndev = ns->ndev;
|
|
||||||
struct device_attribute *dev_attr =
|
|
||||||
container_of(attr, typeof(*dev_attr), attr);
|
|
||||||
|
|
||||||
if (!ndev)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dev_attr->show == nvm_dev_attr_show)
|
|
||||||
return attr->mode;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct attribute_group nvme_nvm_attr_group = {
|
void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
|
||||||
.name = "lightnvm",
|
{
|
||||||
.attrs = nvm_dev_attrs,
|
sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
|
||||||
.is_visible = nvm_dev_attrs_visible,
|
&nvm_dev_attr_group);
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,8 @@ int nvme_reset_ctrl(struct nvme_ctrl *ctrl);
|
||||||
#ifdef CONFIG_NVM
|
#ifdef CONFIG_NVM
|
||||||
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
|
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
|
||||||
void nvme_nvm_unregister(struct nvme_ns *ns);
|
void nvme_nvm_unregister(struct nvme_ns *ns);
|
||||||
extern const struct attribute_group nvme_nvm_attr_group;
|
int nvme_nvm_register_sysfs(struct nvme_ns *ns);
|
||||||
|
void nvme_nvm_unregister_sysfs(struct nvme_ns *ns);
|
||||||
int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
|
int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
|
||||||
#else
|
#else
|
||||||
static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
|
static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
|
||||||
|
|
@ -346,6 +347,11 @@ static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void nvme_nvm_unregister(struct nvme_ns *ns) {};
|
static inline void nvme_nvm_unregister(struct nvme_ns *ns) {};
|
||||||
|
static inline int nvme_nvm_register_sysfs(struct nvme_ns *ns)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) {};
|
||||||
static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd,
|
static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2158,10 +2158,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
|
||||||
if (dev->ctrl.queue_count)
|
if (dev->ctrl.queue_count)
|
||||||
nvme_suspend_queue(&dev->queues[0]);
|
nvme_suspend_queue(&dev->queues[0]);
|
||||||
} else {
|
} else {
|
||||||
if (dev->ctrl.queue_count) {
|
nvme_disable_io_queues(dev, queues);
|
||||||
nvme_disable_io_queues(dev, queues);
|
nvme_disable_admin_queue(dev, shutdown);
|
||||||
nvme_disable_admin_queue(dev, shutdown);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nvme_pci_disable(dev);
|
nvme_pci_disable(dev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3817,6 +3817,150 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFAULT_PCI_RESET_WAIT_TIMEOUT 0
|
||||||
|
#define MIN_PCI_RESET_WAIT_TIMEOUT DEFAULT_PCI_RESET_WAIT_TIMEOUT
|
||||||
|
#define MAX_PCI_RESET_WAIT_TIMEOUT 4
|
||||||
|
|
||||||
|
struct pci_reset_quirk_config {
|
||||||
|
unsigned short vendor;
|
||||||
|
unsigned short device;
|
||||||
|
union { /* 4 bytes in size. */
|
||||||
|
unsigned int timeout;
|
||||||
|
unsigned int reserve;
|
||||||
|
};
|
||||||
|
int (*reset)(struct pci_dev *dev, struct pci_reset_quirk_config *cfg, int probe);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_PCI_RESET_CONFIG_NUM 20
|
||||||
|
static int pci_reset_quirk_config_num = 0;
|
||||||
|
static struct pci_reset_quirk_config pci_reset_quirk_config[MAX_PCI_RESET_CONFIG_NUM] = {
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pci_reset_quirk_no_reset(struct pci_dev *dev,
|
||||||
|
struct pci_reset_quirk_config *cfg, int probe)
|
||||||
|
{
|
||||||
|
pci_info(dev, "do no reset the device\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_no_reset_quirk_get_opt(char *str)
|
||||||
|
{
|
||||||
|
unsigned short vid, did;
|
||||||
|
struct pci_reset_quirk_config *cfg;
|
||||||
|
|
||||||
|
while (str) {
|
||||||
|
char *k = strchr(str, ',');
|
||||||
|
if (k)
|
||||||
|
*k++ = 0;
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
vid = (unsigned short)simple_strtoul(str, &str, 16);
|
||||||
|
did = (unsigned short)simple_strtoul(str + 1, &str, 16);
|
||||||
|
|
||||||
|
cfg = &pci_reset_quirk_config[pci_reset_quirk_config_num++ % MAX_PCI_RESET_CONFIG_NUM];
|
||||||
|
cfg->vendor = vid;
|
||||||
|
cfg->device = did;
|
||||||
|
cfg->reserve = 0;
|
||||||
|
cfg->reset = pci_reset_quirk_no_reset;
|
||||||
|
pr_info("add no reset quirk success: %x:%x\n", vid, did);
|
||||||
|
}
|
||||||
|
str = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_reset_quirk_ssleep_after_sbr(struct pci_dev *dev,
|
||||||
|
struct pci_reset_quirk_config *cfg, int probe)
|
||||||
|
{
|
||||||
|
struct pci_dev *slot = dev->bus->self;
|
||||||
|
u16 reg, timeout = cfg->timeout;
|
||||||
|
|
||||||
|
if (probe)
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
|
if (!timeout)
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
|
pcie_capability_read_word(slot, PCI_EXP_SLTCTL, ®);
|
||||||
|
reg &= (~PCI_EXP_SLTCTL_DLLSCE);
|
||||||
|
pcie_capability_write_word(slot, PCI_EXP_SLTCTL, reg);
|
||||||
|
|
||||||
|
pci_reset_secondary_bus(slot);
|
||||||
|
|
||||||
|
ssleep(timeout);
|
||||||
|
|
||||||
|
pcie_capability_write_word(slot, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_DLLSC);
|
||||||
|
pcie_capability_read_word(slot, PCI_EXP_SLTCTL, ®);
|
||||||
|
reg |= PCI_EXP_SLTCTL_DLLSCE;
|
||||||
|
pcie_capability_write_word(slot, PCI_EXP_SLTCTL, reg);
|
||||||
|
|
||||||
|
pci_info(dev, "do sleep %ds after device reset\n", timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci_reset_timeout_quirk_get_opt(char *str)
|
||||||
|
{
|
||||||
|
unsigned short vid, did;
|
||||||
|
unsigned int t;
|
||||||
|
struct pci_reset_quirk_config *cfg;
|
||||||
|
|
||||||
|
while (str) {
|
||||||
|
char *k = strchr(str, ',');
|
||||||
|
if (k)
|
||||||
|
*k++ = 0;
|
||||||
|
|
||||||
|
if (str) {
|
||||||
|
vid = (unsigned short)simple_strtoul(str, &str, 16);
|
||||||
|
did = (unsigned short)simple_strtoul(str + 1, &str, 16);
|
||||||
|
t = (unsigned int)simple_strtoul(str + 1, &str, 10);
|
||||||
|
|
||||||
|
if (t > MAX_PCI_RESET_WAIT_TIMEOUT
|
||||||
|
|| t < MIN_PCI_RESET_WAIT_TIMEOUT)
|
||||||
|
t = MIN_PCI_RESET_WAIT_TIMEOUT;
|
||||||
|
|
||||||
|
cfg = &pci_reset_quirk_config[pci_reset_quirk_config_num++ % MAX_PCI_RESET_CONFIG_NUM];
|
||||||
|
cfg->vendor = vid;
|
||||||
|
cfg->device = did;
|
||||||
|
cfg->timeout = t;
|
||||||
|
cfg->reset = pci_reset_quirk_ssleep_after_sbr;
|
||||||
|
pr_info("add reset timeout quirk success: %x:%x timeout:%x\n", vid, did, t);
|
||||||
|
}
|
||||||
|
str = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cmdline e.g.: pcireset_quirk=timeout,1ea0:2a16=4,1ea0:2a17=3 pcireset_quirk=noreset,1ea0:2a16,1ea0:2a17
|
||||||
|
*/
|
||||||
|
static int __init pci_reset_quirk_setup(char *str)
|
||||||
|
{
|
||||||
|
if (!strncmp(str, "timeout,", 8)) {
|
||||||
|
pci_reset_timeout_quirk_get_opt(str + 8);
|
||||||
|
} else if (!strncmp(str, "noreset,", 8)) {
|
||||||
|
pci_no_reset_quirk_get_opt(str + 8);
|
||||||
|
} else {
|
||||||
|
pr_err("PCI: Unknown option in pcireset_quirk. '%s'\n", str);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
__setup("pcireset_quirk=", pci_reset_quirk_setup);
|
||||||
|
|
||||||
|
static int pci_reset_quirk_cmdline(struct pci_dev *dev, int probe)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct pci_reset_quirk_config *cfg;
|
||||||
|
|
||||||
|
for (i = 0; i < pci_reset_quirk_config_num && i < MAX_PCI_RESET_CONFIG_NUM; i++){
|
||||||
|
cfg = &pci_reset_quirk_config[i];
|
||||||
|
if (cfg->vendor == dev->vendor &&
|
||||||
|
cfg->device == dev->device &&
|
||||||
|
cfg->reset)
|
||||||
|
return cfg->reset(dev, cfg, probe);
|
||||||
|
}
|
||||||
|
return -ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
|
#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
|
||||||
#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156
|
#define PCI_DEVICE_ID_INTEL_IVB_M_VGA 0x0156
|
||||||
#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166
|
#define PCI_DEVICE_ID_INTEL_IVB_M2_VGA 0x0166
|
||||||
|
|
@ -3830,6 +3974,7 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
|
||||||
reset_ivb_igd },
|
reset_ivb_igd },
|
||||||
{ PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
|
{ PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
|
||||||
reset_chelsio_generic_dev },
|
reset_chelsio_generic_dev },
|
||||||
|
{ PCI_ANY_ID, PCI_ANY_ID, pci_reset_quirk_cmdline },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
|
||||||
gdp->queue = block->request_queue;
|
gdp->queue = block->request_queue;
|
||||||
block->gdp = gdp;
|
block->gdp = gdp;
|
||||||
set_capacity(block->gdp, 0);
|
set_capacity(block->gdp, 0);
|
||||||
device_add_disk(&base->cdev->dev, block->gdp, NULL);
|
device_add_disk(&base->cdev->dev, block->gdp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -677,7 +677,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
get_device(&dev_info->dev);
|
get_device(&dev_info->dev);
|
||||||
device_add_disk(&dev_info->dev, dev_info->gd, NULL);
|
device_add_disk(&dev_info->dev, dev_info->gd);
|
||||||
|
|
||||||
switch (dev_info->segment_type) {
|
switch (dev_info->segment_type) {
|
||||||
case SEG_TYPE_SR:
|
case SEG_TYPE_SR:
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,7 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
|
||||||
|
|
||||||
/* 512 byte sectors */
|
/* 512 byte sectors */
|
||||||
set_capacity(bdev->gendisk, scmdev->size >> 9);
|
set_capacity(bdev->gendisk, scmdev->size >> 9);
|
||||||
device_add_disk(&scmdev->dev, bdev->gendisk, NULL);
|
device_add_disk(&scmdev->dev, bdev->gendisk);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_queue:
|
out_queue:
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ config SCSI_MPT3SAS
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI
|
||||||
select SCSI_SAS_ATTRS
|
select SCSI_SAS_ATTRS
|
||||||
select RAID_ATTRS
|
select RAID_ATTRS
|
||||||
select IRQ_POLL
|
|
||||||
---help---
|
---help---
|
||||||
This driver supports PCI-Express SAS 12Gb/s Host Adapters.
|
This driver supports PCI-Express SAS 12Gb/s Host Adapters.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
EXTRA_CFLAGS := -DCPQ_CIM
|
EXTRA_CFLAGS := -DCPQ_CIM
|
||||||
|
|
||||||
# comment out this line so driver can compile for kernels not having mpt3sas
|
# comment out this line so driver can compile for kernels not having mpt3sas
|
||||||
obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o
|
#obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o
|
||||||
|
obj-m += mpt3sas.o
|
||||||
mpt3sas-y += mpt3sas_base.o \
|
mpt3sas-y += mpt3sas_base.o \
|
||||||
mpt3sas_config.o \
|
mpt3sas_config.o \
|
||||||
mpt3sas_warpdrive.o \
|
mpt3sas_warpdrive.o \
|
||||||
|
|
@ -12,5 +13,4 @@ mpt3sas-y += mpt3sas_base.o \
|
||||||
mpt3sas_transport.o \
|
mpt3sas_transport.o \
|
||||||
mpt3sas_ctl.o \
|
mpt3sas_ctl.o \
|
||||||
mpt3sas_trigger_diag.o \
|
mpt3sas_trigger_diag.o \
|
||||||
mpt3sas_debugfs.o \
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,6 @@ _csmisas_get_cntlr_status(struct MPT3SAS_ADAPTER *ioc,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPI2_IOC_STATE_FAULT:
|
case MPI2_IOC_STATE_FAULT:
|
||||||
case MPI2_IOC_STATE_COREDUMP:
|
|
||||||
karg->Status.uStatus = CSMI_SAS_CNTLR_STATUS_FAILED;
|
karg->Status.uStatus = CSMI_SAS_CNTLR_STATUS_FAILED;
|
||||||
karg->Status.uOfflineReason = 0;
|
karg->Status.uOfflineReason = 0;
|
||||||
break;
|
break;
|
||||||
|
|
@ -2195,7 +2194,7 @@ _csmisas_ssp_passthru(struct MPT3SAS_ADAPTER *ioc,
|
||||||
printk(MPT3SAS_INFO_FMT "issue target reset: handle"
|
printk(MPT3SAS_INFO_FMT "issue target reset: handle"
|
||||||
"(0x%04x)\n", ioc->name, sas_device.handle);
|
"(0x%04x)\n", ioc->name, sas_device.handle);
|
||||||
mpt3sas_scsih_issue_locked_tm(ioc, sas_device.handle, 0, 0, 0,
|
mpt3sas_scsih_issue_locked_tm(ioc, sas_device.handle, 0, 0, 0,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, smid, 30, 0);
|
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30, 0);
|
||||||
if (ioc->scsih_cmds.status & MPT3_CMD_COMPLETE) {
|
if (ioc->scsih_cmds.status & MPT3_CMD_COMPLETE) {
|
||||||
printk(MPT3SAS_INFO_FMT "target reset completed: handle"
|
printk(MPT3SAS_INFO_FMT "target reset completed: handle"
|
||||||
"(0x%04x)\n", ioc->name, sas_device.handle);
|
"(0x%04x)\n", ioc->name, sas_device.handle);
|
||||||
|
|
|
||||||
|
|
@ -126,8 +126,6 @@
|
||||||
* Added MPI2_IOCSTATUS_FAILURE
|
* Added MPI2_IOCSTATUS_FAILURE
|
||||||
* 12-17-18 02.00.54 Bumped MPI2_HEADER_VERSION_UNIT
|
* 12-17-18 02.00.54 Bumped MPI2_HEADER_VERSION_UNIT
|
||||||
* 06-24-19 02.00.55 Bumped MPI2_HEADER_VERSION_UNIT
|
* 06-24-19 02.00.55 Bumped MPI2_HEADER_VERSION_UNIT
|
||||||
* 08-01-19 02.00.56 Bumped MPI2_HEADER_VERSION_UNIT
|
|
||||||
* 10-02-19 02.00.56 Bumped MPI2_HEADER_VERSION_UNIT
|
|
||||||
* --------------------------------------------------------------------------
|
* --------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -171,7 +169,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Unit and Dev versioning for this MPI header set */
|
/* Unit and Dev versioning for this MPI header set */
|
||||||
#define MPI2_HEADER_VERSION_UNIT (0x39)
|
#define MPI2_HEADER_VERSION_UNIT (0x37)
|
||||||
#define MPI2_HEADER_VERSION_DEV (0x00)
|
#define MPI2_HEADER_VERSION_DEV (0x00)
|
||||||
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
|
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
|
||||||
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
|
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
|
||||||
|
|
@ -190,7 +188,6 @@
|
||||||
#define MPI2_IOC_STATE_READY (0x10000000)
|
#define MPI2_IOC_STATE_READY (0x10000000)
|
||||||
#define MPI2_IOC_STATE_OPERATIONAL (0x20000000)
|
#define MPI2_IOC_STATE_OPERATIONAL (0x20000000)
|
||||||
#define MPI2_IOC_STATE_FAULT (0x40000000)
|
#define MPI2_IOC_STATE_FAULT (0x40000000)
|
||||||
#define MPI2_IOC_STATE_COREDUMP (0x50000000)
|
|
||||||
|
|
||||||
#define MPI2_IOC_STATE_MASK (0xF0000000)
|
#define MPI2_IOC_STATE_MASK (0xF0000000)
|
||||||
#define MPI2_IOC_STATE_SHIFT (28)
|
#define MPI2_IOC_STATE_SHIFT (28)
|
||||||
|
|
|
||||||
|
|
@ -252,9 +252,6 @@
|
||||||
* Modify NVMe WriteCache values.
|
* Modify NVMe WriteCache values.
|
||||||
* Add ConfigSource to PCIeIOUnit0.
|
* Add ConfigSource to PCIeIOUnit0.
|
||||||
* Add various PCI id info to PCIeDevice2.
|
* Add various PCI id info to PCIeDevice2.
|
||||||
* 08-01-19 02.00.49 Add MPI26_MANPAGE7_FLAG_X2_X4_SLOT_INFO_VALID
|
|
||||||
* Add MPI26_IOUNITPAGE1_NVME_WRCACHE_SHIFT
|
|
||||||
* Correct def of MPI26_PCIEIOUNIT1_CF_BP_AUTO_CLOCK_ENABLE
|
|
||||||
* --------------------------------------------------------------------------
|
* --------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -903,7 +900,6 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_7
|
||||||
#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
|
#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
|
||||||
|
|
||||||
#define MPI26_MANPAGE7_FLAG_CONN_LANE_USE_PINOUT (0x00000020)
|
#define MPI26_MANPAGE7_FLAG_CONN_LANE_USE_PINOUT (0x00000020)
|
||||||
#define MPI26_MANPAGE7_FLAG_X2_X4_SLOT_INFO_VALID (0x00000010)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic structure to use for product-specific manufacturing pages
|
* Generic structure to use for product-specific manufacturing pages
|
||||||
|
|
@ -975,7 +971,6 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1
|
||||||
|
|
||||||
/* IO Unit Page 1 Flags defines */
|
/* IO Unit Page 1 Flags defines */
|
||||||
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_MASK (0x00030000)
|
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_MASK (0x00030000)
|
||||||
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_SHIFT (16)
|
|
||||||
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_NO_CHANGE (0x00000000)
|
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_NO_CHANGE (0x00000000)
|
||||||
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_ENABLE (0x00010000)
|
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_ENABLE (0x00010000)
|
||||||
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_DISABLE (0x00020000)
|
#define MPI26_IOUNITPAGE1_NVME_WRCACHE_DISABLE (0x00020000)
|
||||||
|
|
@ -3565,7 +3560,7 @@ typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_1
|
||||||
|
|
||||||
/* values for PCIe IO Unit Page 1 ControlFlags */
|
/* values for PCIe IO Unit Page 1 ControlFlags */
|
||||||
#define MPI26_PCIEIOUNIT1_CF_BP_CONFIG_DISABLE (0x0080)
|
#define MPI26_PCIEIOUNIT1_CF_BP_CONFIG_DISABLE (0x0080)
|
||||||
#define MPI26_PCIEIOUNIT1_CF_BP_AUTO_CLOCK_ENABLE (0x0040)
|
#define MPI26_PCIEIOUNIT1_CF_BP_AUTO_CLOCK_ENABLE (0x0060)
|
||||||
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_MASK (0x0030)
|
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_MASK (0x0030)
|
||||||
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_ALL_DIS (0x0000)
|
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_ALL_DIS (0x0000)
|
||||||
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_SRIS_EN (0x0010)
|
#define MPI26_PCIEIOUNIT1_CF_BP_CLK_SRIS_EN (0x0010)
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,9 @@
|
||||||
* 08-14-18 02.06.01 Corrected define for MPI26_IMAGE_HEADER_SIGNATURE0_MPI26
|
* 08-14-18 02.06.01 Corrected define for MPI26_IMAGE_HEADER_SIGNATURE0_MPI26
|
||||||
* 08-28-18 02.06.02 Added MPI2_EXT_IMAGE_TYPE_RDE
|
* 08-28-18 02.06.02 Added MPI2_EXT_IMAGE_TYPE_RDE
|
||||||
* 09-07-18 02.06.03 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES
|
* 09-07-18 02.06.03 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES
|
||||||
* 12-17-18 02.06.04 Added MPI2_EXT_IMAGE_TYPE_PBLP
|
* 12-17-18 02.06.04 Addd MPI2_EXT_IMAGE_TYPE_PBLP
|
||||||
* Shorten some defines to be compatible with DOS
|
* Shorten some defines to be compatible with DOS
|
||||||
* 06-24-19 02.06.05 Whitespace adjustments to help with identifier checking tool.
|
* 06-24-19 02.06.05 Whitespace adjustments to help with identifier checking tool.
|
||||||
* 10-02-19 02.06.06 Added MPI26_IMAGE_HEADER_SIG1_COREDUMP
|
|
||||||
* Added MPI2_FLASH_REGION_COREDUMP
|
|
||||||
*/
|
*/
|
||||||
#ifndef MPI2_IMAGE_H
|
#ifndef MPI2_IMAGE_H
|
||||||
#define MPI2_IMAGE_H
|
#define MPI2_IMAGE_H
|
||||||
|
|
@ -208,7 +206,6 @@ typedef struct _MPI26_COMPONENT_IMAGE_HEADER
|
||||||
#define MPI26_IMAGE_HEADER_SIG1_NVDATA (0x5444564E)
|
#define MPI26_IMAGE_HEADER_SIG1_NVDATA (0x5444564E)
|
||||||
#define MPI26_IMAGE_HEADER_SIG1_GAS_GAUGE (0x20534147)
|
#define MPI26_IMAGE_HEADER_SIG1_GAS_GAUGE (0x20534147)
|
||||||
#define MPI26_IMAGE_HEADER_SIG1_PBLP (0x504C4250)
|
#define MPI26_IMAGE_HEADER_SIG1_PBLP (0x504C4250)
|
||||||
#define MPI26_IMAGE_HEADER_SIG1_COREDUMP (0x504D5544) /* little-endian "DUMP" */
|
|
||||||
|
|
||||||
/**** Definitions for Signature2 field ****/
|
/**** Definitions for Signature2 field ****/
|
||||||
#define MPI26_IMAGE_HEADER_SIGNATURE2_VALUE (0x50584546)
|
#define MPI26_IMAGE_HEADER_SIGNATURE2_VALUE (0x50584546)
|
||||||
|
|
@ -361,7 +358,6 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA
|
||||||
#define MPI2_FLASH_REGION_MR_NVDATA (0x14)
|
#define MPI2_FLASH_REGION_MR_NVDATA (0x14)
|
||||||
#define MPI2_FLASH_REGION_CPLD (0x15)
|
#define MPI2_FLASH_REGION_CPLD (0x15)
|
||||||
#define MPI2_FLASH_REGION_PSOC (0x16)
|
#define MPI2_FLASH_REGION_PSOC (0x16)
|
||||||
#define MPI2_FLASH_REGION_COREDUMP (0x17)
|
|
||||||
|
|
||||||
/* ImageRevision */
|
/* ImageRevision */
|
||||||
#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00)
|
#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00)
|
||||||
|
|
|
||||||
|
|
@ -177,10 +177,6 @@
|
||||||
* Moved FW image definitions ionto new mpi2_image,h
|
* Moved FW image definitions ionto new mpi2_image,h
|
||||||
* 08-14-18 02.00.36 Fixed definition of MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16)
|
* 08-14-18 02.00.36 Fixed definition of MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16)
|
||||||
* 09-07-18 02.00.37 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES
|
* 09-07-18 02.00.37 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES
|
||||||
* 10-02-19 02.00.38 Added MPI26_IOCINIT_CFGFLAGS_COREDUMP_ENABLE
|
|
||||||
* Added MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED
|
|
||||||
* Added MPI2_FW_DOWNLOAD_ITYPE_COREDUMP
|
|
||||||
* Added MPI2_FW_UPLOAD_ITYPE_COREDUMP
|
|
||||||
* --------------------------------------------------------------------------
|
* --------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -254,7 +250,6 @@ typedef struct _MPI2_IOC_INIT_REQUEST
|
||||||
|
|
||||||
/* ConfigurationFlags */
|
/* ConfigurationFlags */
|
||||||
#define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT (0x0001)
|
#define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT (0x0001)
|
||||||
#define MPI26_IOCINIT_CFGFLAGS_COREDUMP_ENABLE (0x0002)
|
|
||||||
|
|
||||||
/* minimum depth for a Reply Descriptor Post Queue */
|
/* minimum depth for a Reply Descriptor Post Queue */
|
||||||
#define MPI2_RDPQ_DEPTH_MIN (16)
|
#define MPI2_RDPQ_DEPTH_MIN (16)
|
||||||
|
|
@ -389,7 +384,6 @@ typedef struct _MPI2_IOC_FACTS_REPLY
|
||||||
/* ProductID field uses MPI2_FW_HEADER_PID_ */
|
/* ProductID field uses MPI2_FW_HEADER_PID_ */
|
||||||
|
|
||||||
/* IOCCapabilities */
|
/* IOCCapabilities */
|
||||||
#define MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED (0x00200000)
|
|
||||||
#define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV (0x00100000)
|
#define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV (0x00100000)
|
||||||
#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000)
|
#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000)
|
||||||
#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000)
|
#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000)
|
||||||
|
|
@ -1516,8 +1510,8 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST
|
||||||
#define MPI2_FW_DOWNLOAD_ITYPE_MR_NVDATA (0x14)
|
#define MPI2_FW_DOWNLOAD_ITYPE_MR_NVDATA (0x14)
|
||||||
#define MPI2_FW_DOWNLOAD_ITYPE_CPLD (0x15) /* MPI v2.6 and newer */
|
#define MPI2_FW_DOWNLOAD_ITYPE_CPLD (0x15) /* MPI v2.6 and newer */
|
||||||
#define MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16) /* MPI v2.6 and newer */
|
#define MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16) /* MPI v2.6 and newer */
|
||||||
#define MPI2_FW_DOWNLOAD_ITYPE_COREDUMP (0x17)
|
|
||||||
#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
|
#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
|
||||||
|
#define MPI2_FW_DOWNLOAD_ITYPE_TERMINATE (0xFF) /* MPI v2.6 and newer */
|
||||||
|
|
||||||
|
|
||||||
/* MPI v2.0 FWDownload TransactionContext Element */
|
/* MPI v2.0 FWDownload TransactionContext Element */
|
||||||
|
|
@ -1618,8 +1612,6 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST
|
||||||
#define MPI2_FW_UPLOAD_ITYPE_CTLR (0x12)
|
#define MPI2_FW_UPLOAD_ITYPE_CTLR (0x12)
|
||||||
#define MPI2_FW_UPLOAD_ITYPE_IMR_FIRMWARE (0x13)
|
#define MPI2_FW_UPLOAD_ITYPE_IMR_FIRMWARE (0x13)
|
||||||
#define MPI2_FW_UPLOAD_ITYPE_MR_NVDATA (0x14)
|
#define MPI2_FW_UPLOAD_ITYPE_MR_NVDATA (0x14)
|
||||||
/* skipping 0x15, 0x16. They are defined in DOWNLOAD, but not needed here */
|
|
||||||
#define MPI2_FW_UPLOAD_ITYPE_COREDUMP (0x17)
|
|
||||||
|
|
||||||
/* MPI v2.0 FWUpload TransactionContext Element */
|
/* MPI v2.0 FWUpload TransactionContext Element */
|
||||||
typedef struct _MPI2_FW_UPLOAD_TCSGE
|
typedef struct _MPI2_FW_UPLOAD_TCSGE
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -73,14 +73,13 @@
|
||||||
#include "mpt3sas_compatibility.h"
|
#include "mpt3sas_compatibility.h"
|
||||||
#include "mpt3sas_debug.h"
|
#include "mpt3sas_debug.h"
|
||||||
#include "mpt3sas_trigger_diag.h"
|
#include "mpt3sas_trigger_diag.h"
|
||||||
#include "mpt3sas_trigger_pages.h"
|
|
||||||
|
|
||||||
/* mpt3sas driver versioning info */
|
/* mpt3sas driver versioning info */
|
||||||
#define MPT3SAS_DRIVER_NAME "mpt3sas"
|
#define MPT3SAS_DRIVER_NAME "mpt3sas"
|
||||||
#define MPT3SAS_AUTHOR "Broadcom Inc. <MPT-FusionLinux.pdl@broadcom.com>"
|
#define MPT3SAS_AUTHOR "Broadcom Inc. <MPT-FusionLinux.pdl@broadcom.com>"
|
||||||
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 & SAS 3.5 Device Driver"
|
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 & SAS 3.5 Device Driver"
|
||||||
#define MPT3SAS_DRIVER_VERSION "37.00.00.00"
|
#define MPT3SAS_DRIVER_VERSION "32.00.00.00"
|
||||||
#define MPT3SAS_MAJOR_VERSION 37
|
#define MPT3SAS_MAJOR_VERSION 32
|
||||||
#define MPT3SAS_MINOR_VERSION 00
|
#define MPT3SAS_MINOR_VERSION 00
|
||||||
#define MPT3SAS_BUILD_VERSION 0
|
#define MPT3SAS_BUILD_VERSION 0
|
||||||
#define MPT3SAS_RELEASE_VERSION 0
|
#define MPT3SAS_RELEASE_VERSION 0
|
||||||
|
|
@ -94,17 +93,6 @@
|
||||||
#define MPT2SAS_BUILD_VERSION 3
|
#define MPT2SAS_BUILD_VERSION 3
|
||||||
#define MPT2SAS_RELEASE_VERSION 0
|
#define MPT2SAS_RELEASE_VERSION 0
|
||||||
|
|
||||||
/* CoreDump: Default timeout */
|
|
||||||
#define MPT3SAS_DEFAULT_COREDUMP_TIMEOUT_SECONDS (15) /* 15 seconds */
|
|
||||||
#define MPT3SAS_TIMESYNC_TIMEOUT_SECONDS (10) /* 10 seconds */
|
|
||||||
#define MPT3SAS_TIMESYNC_UPDATE_INTERVAL (900) /* 15 minutes */
|
|
||||||
#define MPT3SAS_TIMESYNC_UNIT_MASK (0x80) /* bit 7 */
|
|
||||||
#define MPT3SAS_TIMESYNC_MASK (0x7F) /* 0 - 6 bits */
|
|
||||||
#define SECONDS_PER_MIN (60)
|
|
||||||
#define SECONDS_PER_HOUR (3600)
|
|
||||||
#define MPT3SAS_COREDUMP_LOOP_DONE (0xFF)
|
|
||||||
#define MPI26_SET_IOC_PARAMETER_SYNC_TIMESTAMP (0x81)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set MPT3SAS_SG_DEPTH value based on user input.
|
* Set MPT3SAS_SG_DEPTH value based on user input.
|
||||||
*/
|
*/
|
||||||
|
|
@ -490,7 +478,6 @@ struct read_cap_parameter {
|
||||||
#define MPT3SAS_HIGH_IOPS_REPLY_QUEUES 8
|
#define MPT3SAS_HIGH_IOPS_REPLY_QUEUES 8
|
||||||
#define MPT3SAS_HIGH_IOPS_BATCH_COUNT 16
|
#define MPT3SAS_HIGH_IOPS_BATCH_COUNT 16
|
||||||
#define MPT3SAS_GEN35_MAX_MSIX_QUEUES 128
|
#define MPT3SAS_GEN35_MAX_MSIX_QUEUES 128
|
||||||
#define RDPQ_MAX_INDEX_IN_ONE_CHUNK 16
|
|
||||||
|
|
||||||
/* Get status code type(bits 27-25) with status code(bits 24-17)
|
/* Get status code type(bits 27-25) with status code(bits 24-17)
|
||||||
* value from status field.
|
* value from status field.
|
||||||
|
|
@ -672,10 +659,7 @@ struct Mpi2ManufacturingPage11_t {
|
||||||
u8 HostTraceBufferFlags; /* 4Fh */
|
u8 HostTraceBufferFlags; /* 4Fh */
|
||||||
u16 HostTraceBufferMaxSizeKB; /* 50h */
|
u16 HostTraceBufferMaxSizeKB; /* 50h */
|
||||||
u16 HostTraceBufferMinSizeKB; /* 52h */
|
u16 HostTraceBufferMinSizeKB; /* 52h */
|
||||||
u8 CoreDumpTOSec; /* 54h */
|
__le32 Reserved10[2]; /* 54h - 5Bh */
|
||||||
u8 TimeSyncInterval; /* 55h */
|
|
||||||
u16 Reserved9; /* 56h */
|
|
||||||
__le32 Reserved10; /* 58h */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -956,7 +940,6 @@ struct _pcie_device {
|
||||||
u8 *serial_number;
|
u8 *serial_number;
|
||||||
u8 reset_timeout;
|
u8 reset_timeout;
|
||||||
u8 access_status;
|
u8 access_status;
|
||||||
u16 shutdown_latency;
|
|
||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1093,7 +1076,6 @@ struct _sas_port {
|
||||||
* @handle: device handle for this phy
|
* @handle: device handle for this phy
|
||||||
* @attached_handle: device handle for attached device
|
* @attached_handle: device handle for attached device
|
||||||
* @phy_belongs_to_port: port has been created for this phy
|
* @phy_belongs_to_port: port has been created for this phy
|
||||||
* @hba_vphy: flag to identify HBA vSES device phy
|
|
||||||
* @port: hba port entry
|
* @port: hba port entry
|
||||||
*/
|
*/
|
||||||
struct _sas_phy {
|
struct _sas_phy {
|
||||||
|
|
@ -1105,7 +1087,6 @@ struct _sas_phy {
|
||||||
u16 handle;
|
u16 handle;
|
||||||
u16 attached_handle;
|
u16 attached_handle;
|
||||||
u8 phy_belongs_to_port;
|
u8 phy_belongs_to_port;
|
||||||
u8 hba_vphy;
|
|
||||||
struct hba_port *port;
|
struct hba_port *port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1123,7 +1104,6 @@ struct _sas_phy {
|
||||||
* @port: hba port entry
|
* @port: hba port entry
|
||||||
* @phy: a list of phys that make up this sas_host/expander
|
* @phy: a list of phys that make up this sas_host/expander
|
||||||
* @sas_port_list: list of ports attached to this sas_host/expander
|
* @sas_port_list: list of ports attached to this sas_host/expander
|
||||||
* @rphy: sas_rphy object of this expander
|
|
||||||
*/
|
*/
|
||||||
struct _sas_node {
|
struct _sas_node {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
@ -1138,7 +1118,6 @@ struct _sas_node {
|
||||||
struct hba_port *port;
|
struct hba_port *port;
|
||||||
struct _sas_phy *phy;
|
struct _sas_phy *phy;
|
||||||
struct list_head sas_port_list;
|
struct list_head sas_port_list;
|
||||||
struct sas_rphy *rphy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1374,87 +1353,25 @@ struct mpt3sas_port_facts {
|
||||||
struct reply_post_struct {
|
struct reply_post_struct {
|
||||||
Mpi2ReplyDescriptorsUnion_t *reply_post_free;
|
Mpi2ReplyDescriptorsUnion_t *reply_post_free;
|
||||||
dma_addr_t reply_post_free_dma;
|
dma_addr_t reply_post_free_dma;
|
||||||
};
|
struct dma_pool *dma_pool;
|
||||||
|
|
||||||
/**
|
|
||||||
* struct virtual_phy - vSES phy structure
|
|
||||||
* sas_address: SAS Address of vSES device
|
|
||||||
* phy_mask: vSES device's phy number
|
|
||||||
* flags: flags used to manage this structure
|
|
||||||
*/
|
|
||||||
struct virtual_phy {
|
|
||||||
struct list_head list;
|
|
||||||
u64 sas_address;
|
|
||||||
u32 phy_mask;
|
|
||||||
u8 flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MPT_VPHY_FLAG_DIRTY_PHY 0x01
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct hba_port - Saves each HBA's Wide/Narrow port info
|
* struct hba_port - Saves each HBA's Wide/Narrow port info
|
||||||
* @port_id: port number
|
* @port_id: port number
|
||||||
* @sas_address: sas address of this wide/narrow port's attached device
|
* @sas_address: sas address of this wide/narrow port's attached device
|
||||||
* @phy_mask: HBA PHY's belonging to this port
|
* @phy_mask: HBA PHY's belonging to this port
|
||||||
* @flags: hba port flags
|
* @flags: hba port flags
|
||||||
* @vphys_mask : mask of vSES devices Phy number
|
|
||||||
* @vphys_list : list containing vSES device structures
|
|
||||||
*/
|
*/
|
||||||
struct hba_port {
|
struct hba_port {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
u8 port_id;
|
||||||
u64 sas_address;
|
u64 sas_address;
|
||||||
u32 phy_mask;
|
u32 phy_mask;
|
||||||
u8 port_id;
|
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u32 vphys_mask;
|
|
||||||
struct list_head vphys_list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct htb_rel_query - diagnostic buffer release reason
|
|
||||||
* @unique_id - unique id associated with this buffer.
|
|
||||||
* @buffer_rel_condition - Release condition ioctl/sysfs/reset
|
|
||||||
* @reserved
|
|
||||||
* @trigger_type - Master/Event/scsi/MPI
|
|
||||||
* @trigger_info_dwords - Data Correspondig to trigger type
|
|
||||||
*/
|
|
||||||
struct htb_rel_query
|
|
||||||
{
|
|
||||||
u16 buffer_rel_condition;
|
|
||||||
u16 reserved;
|
|
||||||
u32 trigger_type;
|
|
||||||
u32 trigger_info_dwords[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Buffer_rel_condition bit fields */
|
|
||||||
|
|
||||||
/* Bit 0 - Diag Buffer not Released */
|
|
||||||
#define MPT3_DIAG_BUFFER_NOT_RELEASED (0x00)
|
|
||||||
/* Bit 0 - Diag Buffer Released */
|
|
||||||
#define MPT3_DIAG_BUFFER_RELEASED (0x01)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bit 1 - Diag Buffer Released by IOCTL,
|
|
||||||
* This bit is valid only if Bit 0 is one
|
|
||||||
*/
|
|
||||||
#define MPT3_DIAG_BUFFER_REL_IOCTL (0x02 | MPT3_DIAG_BUFFER_RELEASED)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bit 2 - Diag Buffer Released by Trigger,
|
|
||||||
* This bit is valid only if Bit 0 is one
|
|
||||||
*/
|
|
||||||
#define MPT3_DIAG_BUFFER_REL_TRIGGER (0x04 | MPT3_DIAG_BUFFER_RELEASED)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bit 3 - Diag Buffer Released by SysFs,
|
|
||||||
* This bit is valid only if Bit 0 is one
|
|
||||||
*/
|
|
||||||
#define MPT3_DIAG_BUFFER_REL_SYSFS (0x08 | MPT3_DIAG_BUFFER_RELEASED)
|
|
||||||
|
|
||||||
/* DIAG RESET Master trigger flags */
|
|
||||||
#define MPT_DIAG_RESET_ISSUED_BY_DRIVER 0x00000000
|
|
||||||
#define MPT_DIAG_RESET_ISSUED_BY_USER 0x00000001
|
|
||||||
|
|
||||||
/* hba port flags */
|
/* hba port flags */
|
||||||
#define HBA_PORT_FLAG_DIRTY_PORT 0x01
|
#define HBA_PORT_FLAG_DIRTY_PORT 0x01
|
||||||
#define HBA_PORT_FLAG_NEW_PORT 0x02
|
#define HBA_PORT_FLAG_NEW_PORT 0x02
|
||||||
|
|
@ -1488,8 +1405,6 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
||||||
* @firmware_event_thread: ""
|
* @firmware_event_thread: ""
|
||||||
* @fw_event_lock:
|
* @fw_event_lock:
|
||||||
* @fw_event_list: list of fw events
|
* @fw_event_list: list of fw events
|
||||||
* @current_evet: current processing firmware event
|
|
||||||
* @fw_event_cleanup: set to one while cleaning up the fw events
|
|
||||||
* @aen_event_read_flag: event log was read
|
* @aen_event_read_flag: event log was read
|
||||||
* @broadcast_aen_busy: broadcast aen waiting to be serviced
|
* @broadcast_aen_busy: broadcast aen waiting to be serviced
|
||||||
* @shost_recovery: host reset in progress
|
* @shost_recovery: host reset in progress
|
||||||
|
|
@ -1513,13 +1428,10 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
|
||||||
* @total_io_cnt: Gives total IO count, used to load balance the interrupts
|
* @total_io_cnt: Gives total IO count, used to load balance the interrupts
|
||||||
* @high_iops_outstanding: used to load balance the interrupts within high iops reply queues
|
* @high_iops_outstanding: used to load balance the interrupts within high iops reply queues
|
||||||
* @high_iops_queues: high iops reply queues count
|
* @high_iops_queues: high iops reply queues count
|
||||||
* @drv_internal_flags: Bit map internal to driver
|
|
||||||
* @drv_support_bitmap: driver's supported feature bit map
|
* @drv_support_bitmap: driver's supported feature bit map
|
||||||
* @msix_load_balance: Enables load balancing of interrupts across the multiple MSIXs
|
* @msix_load_balance: Enables load balancing of interrupts across the multiple MSIXs
|
||||||
* @thresh_hold: Max number of reply descriptors processed before updating Host Index
|
* @thresh_hold: Max number of reply descriptors processed before updating Host Index
|
||||||
* @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands
|
* @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands
|
||||||
* @timestamp_update_count: Counter to fire timeSync command
|
|
||||||
* time_sync_interval: Time sync interval read from man page 11
|
|
||||||
* @scsi_io_cb_idx: shost generated commands
|
* @scsi_io_cb_idx: shost generated commands
|
||||||
* @tm_cb_idx: task management commands
|
* @tm_cb_idx: task management commands
|
||||||
* @scsih_cb_idx: scsih internal commands
|
* @scsih_cb_idx: scsih internal commands
|
||||||
|
|
@ -1705,8 +1617,6 @@ struct MPT3SAS_ADAPTER {
|
||||||
struct workqueue_struct *firmware_event_thread;
|
struct workqueue_struct *firmware_event_thread;
|
||||||
spinlock_t fw_event_lock;
|
spinlock_t fw_event_lock;
|
||||||
struct list_head fw_event_list;
|
struct list_head fw_event_list;
|
||||||
struct fw_event_work *current_event;
|
|
||||||
u8 fw_events_cleanup;
|
|
||||||
|
|
||||||
/* misc flags */
|
/* misc flags */
|
||||||
int aen_event_read_flag;
|
int aen_event_read_flag;
|
||||||
|
|
@ -1744,20 +1654,13 @@ struct MPT3SAS_ADAPTER {
|
||||||
u32 ioc_reset_count;
|
u32 ioc_reset_count;
|
||||||
MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
|
MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
|
||||||
u32 non_operational_loop;
|
u32 non_operational_loop;
|
||||||
u8 ioc_coredump_loop;
|
|
||||||
u32 timestamp_update_count;
|
|
||||||
u32 time_sync_interval;
|
|
||||||
u8 multipath_on_hba;
|
u8 multipath_on_hba;
|
||||||
atomic64_t total_io_cnt;
|
atomic64_t total_io_cnt;
|
||||||
atomic64_t high_iops_outstanding;
|
atomic64_t high_iops_outstanding;
|
||||||
bool msix_load_balance;
|
bool msix_load_balance;
|
||||||
u16 thresh_hold;
|
u16 thresh_hold;
|
||||||
u8 high_iops_queues;
|
u8 high_iops_queues;
|
||||||
u32 drv_internal_flags;
|
|
||||||
u32 drv_support_bitmap;
|
u32 drv_support_bitmap;
|
||||||
u32 dma_mask;
|
|
||||||
bool enable_sdev_max_qd;
|
|
||||||
bool use_32bit_dma;
|
|
||||||
|
|
||||||
/* internal commands, callback index */
|
/* internal commands, callback index */
|
||||||
u8 scsi_io_cb_idx;
|
u8 scsi_io_cb_idx;
|
||||||
|
|
@ -1810,7 +1713,6 @@ struct MPT3SAS_ADAPTER {
|
||||||
u8 disable_eedp_support;
|
u8 disable_eedp_support;
|
||||||
u8 tm_custom_handling;
|
u8 tm_custom_handling;
|
||||||
u8 nvme_abort_timeout;
|
u8 nvme_abort_timeout;
|
||||||
u16 max_shutdown_latency;
|
|
||||||
|
|
||||||
/* static config pages */
|
/* static config pages */
|
||||||
struct mpt3sas_facts facts;
|
struct mpt3sas_facts facts;
|
||||||
|
|
@ -1944,6 +1846,9 @@ struct MPT3SAS_ADAPTER {
|
||||||
u16 reply_post_queue_depth;
|
u16 reply_post_queue_depth;
|
||||||
struct reply_post_struct *reply_post;
|
struct reply_post_struct *reply_post;
|
||||||
struct dma_pool *reply_post_free_dma_pool;
|
struct dma_pool *reply_post_free_dma_pool;
|
||||||
|
struct dma_pool *reply_post_free_dma_pool_align;
|
||||||
|
struct dma_pool *reply_post_free_dma_pool_mod_rdpq_set;
|
||||||
|
struct dma_pool *reply_post_free_dma_pool_mod_rdpq_set_align;
|
||||||
struct dma_pool *reply_post_free_array_dma_pool;
|
struct dma_pool *reply_post_free_array_dma_pool;
|
||||||
Mpi2IOCInitRDPQArrayEntry *reply_post_free_array;
|
Mpi2IOCInitRDPQArrayEntry *reply_post_free_array;
|
||||||
dma_addr_t reply_post_free_array_dma;
|
dma_addr_t reply_post_free_array_dma;
|
||||||
|
|
@ -1979,8 +1884,6 @@ struct MPT3SAS_ADAPTER {
|
||||||
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
|
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
|
||||||
u32 ring_buffer_offset;
|
u32 ring_buffer_offset;
|
||||||
u32 ring_buffer_sz;
|
u32 ring_buffer_sz;
|
||||||
struct htb_rel_query htb_rel;
|
|
||||||
u8 reset_from_user;
|
|
||||||
#if defined(TARGET_MODE)
|
#if defined(TARGET_MODE)
|
||||||
char stm_name[MPT_NAME_LENGTH];
|
char stm_name[MPT_NAME_LENGTH];
|
||||||
u8 stm_io_cb_idx; /* normal io */
|
u8 stm_io_cb_idx; /* normal io */
|
||||||
|
|
@ -2019,7 +1922,6 @@ struct MPT3SAS_ADAPTER {
|
||||||
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
|
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
|
||||||
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
|
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
|
||||||
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
|
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
|
||||||
u8 supports_trigger_pages;
|
|
||||||
void *device_remove_in_progress;
|
void *device_remove_in_progress;
|
||||||
u16 device_remove_in_progress_sz;
|
u16 device_remove_in_progress_sz;
|
||||||
u8 *tm_tr_retry;
|
u8 *tm_tr_retry;
|
||||||
|
|
@ -2027,22 +1929,10 @@ struct MPT3SAS_ADAPTER {
|
||||||
u8 temp_sensors_count;
|
u8 temp_sensors_count;
|
||||||
u8 is_gen35_ioc;
|
u8 is_gen35_ioc;
|
||||||
u8 is_aero_ioc;
|
u8 is_aero_ioc;
|
||||||
#ifdef CONFIG_DEBUG_FS
|
|
||||||
struct dentry *debugfs_root;
|
|
||||||
struct dentry *ioc_dump;
|
|
||||||
#endif
|
|
||||||
struct list_head port_table_list;
|
struct list_head port_table_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpt3sas_debugfs_buffer {
|
#define MPT_DRV_SUPPORT_BITMAP_MEMMOVE 0x00000001
|
||||||
void *buf;
|
|
||||||
u32 len;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MPT_DRV_SUPPORT_BITMAP_MEMMOVE 0x00000001
|
|
||||||
#define MPT_DRV_SUPPORT_BITMAP_ADDNLQUERY 0x00000002
|
|
||||||
|
|
||||||
#define MPT_DRV_INTERNAL_BITMAP_BLK_MQ 0x00000001
|
|
||||||
|
|
||||||
typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||||
u32 reply);
|
u32 reply);
|
||||||
|
|
@ -2093,7 +1983,7 @@ __le64 mpt3sas_base_get_sense_buffer_dma_64(struct MPT3SAS_ADAPTER *ioc,
|
||||||
u16 smid);
|
u16 smid);
|
||||||
void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
||||||
dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
|
||||||
void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll);
|
void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
|
||||||
|
|
||||||
/* hi-priority queue */
|
/* hi-priority queue */
|
||||||
u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
|
u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);
|
||||||
|
|
@ -2117,13 +2007,6 @@ u32 mpt3sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked);
|
||||||
int _base_check_and_get_msix_vectors(struct pci_dev *pdev);
|
int _base_check_and_get_msix_vectors(struct pci_dev *pdev);
|
||||||
|
|
||||||
void mpt3sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code);
|
void mpt3sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code);
|
||||||
#define mpt3sas_print_fault_code(ioc, fault_code) \
|
|
||||||
printk(MPT3SAS_ERR_FMT "fault info from func: %s\n", ioc->name, __func__); \
|
|
||||||
mpt3sas_base_fault_info (ioc, fault_code)
|
|
||||||
|
|
||||||
void mpt3sas_base_coredump_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code);
|
|
||||||
int mpt3sas_base_wait_for_coredump_completion(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
const char *caller);
|
|
||||||
int mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc,
|
int mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc,
|
||||||
Mpi2SasIoUnitControlReply_t *mpi_reply,
|
Mpi2SasIoUnitControlReply_t *mpi_reply,
|
||||||
Mpi2SasIoUnitControlRequest_t *mpi_request);
|
Mpi2SasIoUnitControlRequest_t *mpi_request);
|
||||||
|
|
@ -2155,9 +2038,7 @@ void mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc);
|
||||||
void mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
|
void mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
|
||||||
u8 mpt3sas_base_check_cmd_timeout(struct MPT3SAS_ADAPTER *ioc,
|
u8 mpt3sas_base_check_cmd_timeout(struct MPT3SAS_ADAPTER *ioc,
|
||||||
u8 status, void *mpi_request, int sz);
|
u8 status, void *mpi_request, int sz);
|
||||||
#define mpt3sas_check_cmd_timeout(ioc, status, mpi_request, sz, issue_reset) \
|
|
||||||
printk(MPT3SAS_ERR_FMT "In func: %s\n", ioc->name, __func__); \
|
|
||||||
issue_reset = mpt3sas_base_check_cmd_timeout(ioc, status, mpi_request, sz)
|
|
||||||
|
|
||||||
int mpt3sas_wait_for_ioc_to_operational(struct MPT3SAS_ADAPTER *ioc,
|
int mpt3sas_wait_for_ioc_to_operational(struct MPT3SAS_ADAPTER *ioc,
|
||||||
int wait_count);
|
int wait_count);
|
||||||
|
|
@ -2165,7 +2046,6 @@ void mpt3sas_base_start_hba_unplug_watchdog(struct MPT3SAS_ADAPTER *ioc);
|
||||||
void mpt3sas_base_stop_hba_unplug_watchdog(struct MPT3SAS_ADAPTER *ioc);
|
void mpt3sas_base_stop_hba_unplug_watchdog(struct MPT3SAS_ADAPTER *ioc);
|
||||||
int mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type);
|
int mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type);
|
||||||
void mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc);
|
void mpt3sas_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc);
|
||||||
void mpt3sas_base_unmask_interrupts(struct MPT3SAS_ADAPTER *ioc);
|
|
||||||
|
|
||||||
/* scsih shared API */
|
/* scsih shared API */
|
||||||
extern char driver_name[MPT_NAME_LENGTH];
|
extern char driver_name[MPT_NAME_LENGTH];
|
||||||
|
|
@ -2190,9 +2070,7 @@ void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc,
|
||||||
u8 mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc,
|
u8 mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc,
|
||||||
u16 smid);
|
u16 smid);
|
||||||
struct hba_port *
|
struct hba_port *
|
||||||
mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port, u8 skip_dirty_flag);
|
mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port);
|
||||||
struct virtual_phy *
|
|
||||||
mpt3sas_get_vphy_by_phy(struct MPT3SAS_ADAPTER *ioc, struct hba_port *port, u32 phy);
|
|
||||||
|
|
||||||
struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
|
struct _sas_node *mpt3sas_scsih_expander_find_by_handle(
|
||||||
struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
|
|
@ -2220,8 +2098,6 @@ _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc,
|
||||||
void
|
void
|
||||||
mpt3sas_scsih_clear_outstanding_scsi_tm_commands(struct MPT3SAS_ADAPTER *ioc);
|
mpt3sas_scsih_clear_outstanding_scsi_tm_commands(struct MPT3SAS_ADAPTER *ioc);
|
||||||
u32 base_mod64(u64 dividend, u32 divisor);
|
u32 base_mod64(u64 dividend, u32 divisor);
|
||||||
void
|
|
||||||
mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _scsih_is_pcie_scsi_device - determines if device is an pcie scsi device
|
* _scsih_is_pcie_scsi_device - determines if device is an pcie scsi device
|
||||||
|
|
@ -2338,33 +2214,6 @@ int mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
|
||||||
int
|
int
|
||||||
mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
|
mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
|
Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz);
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page);
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page);
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page);
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page);
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page);
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set);
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set);
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set);
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set);
|
|
||||||
|
|
||||||
/* ctl shared API */
|
/* ctl shared API */
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
|
|
@ -2462,11 +2311,6 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
||||||
|
|
||||||
void _scsih_hide_unhide_sas_devices(struct MPT3SAS_ADAPTER *ioc);
|
void _scsih_hide_unhide_sas_devices(struct MPT3SAS_ADAPTER *ioc);
|
||||||
|
|
||||||
void mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc);
|
|
||||||
void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc);
|
|
||||||
void mpt3sas_init_debugfs(void);
|
|
||||||
void mpt3sas_exit_debugfs(void);
|
|
||||||
|
|
||||||
#ifdef MPT2SAS_WD_DDIOCOUNT
|
#ifdef MPT2SAS_WD_DDIOCOUNT
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
ssize_t
|
ssize_t
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,9 @@ _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
|
||||||
Mpi2ConfigRequest_t *mpi_request;
|
Mpi2ConfigRequest_t *mpi_request;
|
||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
|
|
||||||
|
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
||||||
|
return;
|
||||||
|
|
||||||
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
||||||
switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
|
switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
|
||||||
case MPI2_CONFIG_PAGETYPE_IO_UNIT:
|
case MPI2_CONFIG_PAGETYPE_IO_UNIT:
|
||||||
|
|
@ -270,8 +273,7 @@ mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
|
||||||
mpi_reply->MsgLength*4);
|
mpi_reply->MsgLength*4);
|
||||||
}
|
}
|
||||||
ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
|
ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
|
||||||
if (ioc->logging_level & MPT_DEBUG_CONFIG)
|
_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
|
||||||
_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
|
|
||||||
ioc->config_cmds.smid = USHORT_MAX;
|
ioc->config_cmds.smid = USHORT_MAX;
|
||||||
complete(&ioc->config_cmds.done);
|
complete(&ioc->config_cmds.done);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -307,7 +309,6 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
u8 retry_count, issue_host_reset = 0;
|
u8 retry_count, issue_host_reset = 0;
|
||||||
struct config_request mem;
|
struct config_request mem;
|
||||||
u32 ioc_status = UINT_MAX;
|
u32 ioc_status = UINT_MAX;
|
||||||
u8 issue_reset;
|
|
||||||
|
|
||||||
mutex_lock(&ioc->config_cmds.mutex);
|
mutex_lock(&ioc->config_cmds.mutex);
|
||||||
if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
|
if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
|
||||||
|
|
@ -380,24 +381,19 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
|
memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
|
||||||
memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
|
|
||||||
ioc->config_cmds.status = MPT3_CMD_PENDING;
|
ioc->config_cmds.status = MPT3_CMD_PENDING;
|
||||||
config_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
config_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
||||||
ioc->config_cmds.smid = smid;
|
ioc->config_cmds.smid = smid;
|
||||||
memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
|
memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
|
||||||
if (ioc->logging_level & MPT_DEBUG_CONFIG)
|
_config_display_some_debug(ioc, smid, "config_request", NULL);
|
||||||
_config_display_some_debug(ioc, smid, "config_request", NULL);
|
|
||||||
init_completion(&ioc->config_cmds.done);
|
init_completion(&ioc->config_cmds.done);
|
||||||
ioc->put_smid_default(ioc, smid);
|
ioc->put_smid_default(ioc, smid);
|
||||||
wait_for_completion_timeout(&ioc->config_cmds.done,
|
wait_for_completion_timeout(&ioc->config_cmds.done,
|
||||||
timeout*HZ);
|
timeout*HZ);
|
||||||
if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
|
if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
|
||||||
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
mpt3sas_base_check_cmd_timeout(ioc,
|
||||||
_config_display_some_debug(ioc, smid,
|
|
||||||
"config_request no reply", NULL);
|
|
||||||
mpt3sas_check_cmd_timeout(ioc,
|
|
||||||
ioc->config_cmds.status, mpi_request,
|
ioc->config_cmds.status, mpi_request,
|
||||||
sizeof(Mpi2ConfigRequest_t)/4, issue_reset);
|
sizeof(Mpi2ConfigRequest_t)/4);
|
||||||
retry_count++;
|
retry_count++;
|
||||||
if (ioc->config_cmds.smid == smid)
|
if (ioc->config_cmds.smid == smid)
|
||||||
mpt3sas_base_free_smid(ioc, smid);
|
mpt3sas_base_free_smid(ioc, smid);
|
||||||
|
|
@ -417,11 +413,8 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
/* Reply Frame Sanity Checks to workaround FW issues */
|
/* Reply Frame Sanity Checks to workaround FW issues */
|
||||||
if ((mpi_request->Header.PageType & 0xF) !=
|
if ((mpi_request->Header.PageType & 0xF) !=
|
||||||
(mpi_reply->Header.PageType & 0xF)) {
|
(mpi_reply->Header.PageType & 0xF)) {
|
||||||
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
|
||||||
_config_display_some_debug(ioc, smid,
|
|
||||||
"config_request", NULL);
|
|
||||||
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
||||||
_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
|
_debug_dump_reply(mpi_reply, ioc->request_sz/4);
|
||||||
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
||||||
" mpi_reply mismatch: Requested PageType(0x%02x)"
|
" mpi_reply mismatch: Requested PageType(0x%02x)"
|
||||||
" Reply PageType(0x%02x)\n",
|
" Reply PageType(0x%02x)\n",
|
||||||
|
|
@ -433,11 +426,8 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
if (((mpi_request->Header.PageType & 0xF) ==
|
if (((mpi_request->Header.PageType & 0xF) ==
|
||||||
MPI2_CONFIG_PAGETYPE_EXTENDED) &&
|
MPI2_CONFIG_PAGETYPE_EXTENDED) &&
|
||||||
mpi_request->ExtPageType != mpi_reply->ExtPageType) {
|
mpi_request->ExtPageType != mpi_reply->ExtPageType) {
|
||||||
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
|
||||||
_config_display_some_debug(ioc, smid,
|
|
||||||
"config_request", NULL);
|
|
||||||
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
||||||
_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
|
_debug_dump_reply(mpi_reply, ioc->request_sz/4);
|
||||||
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
||||||
" mpi_reply mismatch: Requested ExtPageType(0x%02x)"
|
" mpi_reply mismatch: Requested ExtPageType(0x%02x)"
|
||||||
" Reply ExtPageType(0x%02x)\n",
|
" Reply ExtPageType(0x%02x)\n",
|
||||||
|
|
@ -461,11 +451,8 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
if (p) {
|
if (p) {
|
||||||
if ((mpi_request->Header.PageType & 0xF) !=
|
if ((mpi_request->Header.PageType & 0xF) !=
|
||||||
(p[3] & 0xF)) {
|
(p[3] & 0xF)) {
|
||||||
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
|
||||||
_config_display_some_debug(ioc, smid,
|
|
||||||
"config_request", NULL);
|
|
||||||
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
||||||
_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
|
_debug_dump_reply(mpi_reply, ioc->request_sz/4);
|
||||||
_debug_dump_config(p, min_t(u16, mem.sz,
|
_debug_dump_config(p, min_t(u16, mem.sz,
|
||||||
config_page_sz)/4);
|
config_page_sz)/4);
|
||||||
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
||||||
|
|
@ -480,11 +467,8 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
|
||||||
if (((mpi_request->Header.PageType & 0xF) ==
|
if (((mpi_request->Header.PageType & 0xF) ==
|
||||||
MPI2_CONFIG_PAGETYPE_EXTENDED) &&
|
MPI2_CONFIG_PAGETYPE_EXTENDED) &&
|
||||||
(mpi_request->ExtPageType != p[6])) {
|
(mpi_request->ExtPageType != p[6])) {
|
||||||
if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
|
|
||||||
_config_display_some_debug(ioc, smid,
|
|
||||||
"config_request", NULL);
|
|
||||||
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
_debug_dump_mf(mpi_request, ioc->request_sz/4);
|
||||||
_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
|
_debug_dump_reply(mpi_reply, ioc->request_sz/4);
|
||||||
_debug_dump_config(p, min_t(u16, mem.sz,
|
_debug_dump_config(p, min_t(u16, mem.sz,
|
||||||
config_page_sz)/4);
|
config_page_sz)/4);
|
||||||
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
panic(MPT3SAS_WARN_FMT "%s: Firmware BUG:"
|
||||||
|
|
@ -1769,766 +1753,6 @@ mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 0;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_set_driver_trigger_pg0 - write driver trigger page 0
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 0;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
|
||||||
_config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @trigger_flags: trigger type bit map
|
|
||||||
* @set: set ot clear trigger values
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
u16 trigger_flag, bool set)
|
|
||||||
{
|
|
||||||
Mpi26DriverTriggerPage0_t tg_pg0;
|
|
||||||
Mpi2ConfigReply_t mpi_reply;
|
|
||||||
int rc;
|
|
||||||
u16 flags, ioc_status;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set)
|
|
||||||
flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
|
|
||||||
else
|
|
||||||
flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
|
|
||||||
|
|
||||||
tg_pg0.TriggerFlags = cpu_to_le16(flags);
|
|
||||||
|
|
||||||
rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 1;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_set_driver_trigger_pg1 - write driver trigger page 1
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 1;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
|
||||||
_config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @master_tg: Master trigger bit map
|
|
||||||
* @set: set ot clear trigger values
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
|
|
||||||
{
|
|
||||||
Mpi26DriverTriggerPage1_t tg_pg1;
|
|
||||||
Mpi2ConfigReply_t mpi_reply;
|
|
||||||
int rc;
|
|
||||||
u16 ioc_status;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set) {
|
|
||||||
tg_pg1.NumMasterTrigger = cpu_to_le16(1);
|
|
||||||
tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
|
|
||||||
master_tg->MasterData);
|
|
||||||
} else {
|
|
||||||
tg_pg1.NumMasterTrigger = 0;
|
|
||||||
tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 2;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_set_driver_trigger_pg2 - write driver trigger page 2
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 2;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
|
||||||
_config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @event_tg: list of Event Triggers
|
|
||||||
* @set: set ot clear trigger values
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
|
|
||||||
{
|
|
||||||
Mpi26DriverTriggerPage2_t tg_pg2;
|
|
||||||
Mpi2ConfigReply_t mpi_reply;
|
|
||||||
int rc, i, count;
|
|
||||||
u16 ioc_status;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set) {
|
|
||||||
count = event_tg->ValidEntries;
|
|
||||||
tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
tg_pg2.MPIEventTriggers[i].MPIEventCode =
|
|
||||||
cpu_to_le16(
|
|
||||||
event_tg->EventTriggerEntry[i].EventValue);
|
|
||||||
tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
|
|
||||||
cpu_to_le16(
|
|
||||||
event_tg->EventTriggerEntry[i].LogEntryQualifier);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tg_pg2.NumMPIEventTrigger = 0;
|
|
||||||
memset(&tg_pg2.MPIEventTriggers[0], 0,
|
|
||||||
NUM_VALID_ENTRIES * sizeof(
|
|
||||||
MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 3;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_set_driver_trigger_pg3 - write driver trigger page 3
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 3;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
|
||||||
_config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @scsi_tg: scsi trigger list
|
|
||||||
* @set: set ot clear trigger values
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
|
|
||||||
{
|
|
||||||
Mpi26DriverTriggerPage3_t tg_pg3;
|
|
||||||
Mpi2ConfigReply_t mpi_reply;
|
|
||||||
int rc, i, count;
|
|
||||||
u16 ioc_status;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set) {
|
|
||||||
count = scsi_tg->ValidEntries;
|
|
||||||
tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
tg_pg3.SCSISenseTriggers[i].ASCQ =
|
|
||||||
scsi_tg->SCSITriggerEntry[i].ASCQ;
|
|
||||||
tg_pg3.SCSISenseTriggers[i].ASC =
|
|
||||||
scsi_tg->SCSITriggerEntry[i].ASC;
|
|
||||||
tg_pg3.SCSISenseTriggers[i].SenseKey =
|
|
||||||
scsi_tg->SCSITriggerEntry[i].SenseKey;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tg_pg3.NumSCSISenseTrigger = 0;
|
|
||||||
memset(&tg_pg3.SCSISenseTriggers[0], 0,
|
|
||||||
NUM_VALID_ENTRIES * sizeof(
|
|
||||||
MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
out:
|
|
||||||
mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 4;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_set_driver_trigger_pg4 - write driver trigger page 4
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_reply: reply mf payload returned from firmware
|
|
||||||
* @config_page: contents of the config page
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
|
|
||||||
{
|
|
||||||
Mpi2ConfigRequest_t mpi_request;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
|
|
||||||
mpi_request.Function = MPI2_FUNCTION_CONFIG;
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
|
||||||
mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
|
||||||
mpi_request.ExtPageType =
|
|
||||||
MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
|
|
||||||
mpi_request.Header.PageNumber = 4;
|
|
||||||
mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
|
|
||||||
ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
|
|
||||||
if (r)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
|
||||||
_config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
|
|
||||||
r = _config_request(ioc, &mpi_request, mpi_reply,
|
|
||||||
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
|
|
||||||
sizeof(*config_page));
|
|
||||||
out:
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @mpi_tg: mpi trigger list
|
|
||||||
* @set: set ot clear trigger values
|
|
||||||
* Context: sleep.
|
|
||||||
*
|
|
||||||
* Returns 0 for success, non-zero for failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
|
|
||||||
{
|
|
||||||
Mpi26DriverTriggerPage4_t tg_pg4;
|
|
||||||
Mpi2ConfigReply_t mpi_reply;
|
|
||||||
int rc, i, count;
|
|
||||||
u16 ioc_status;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set) {
|
|
||||||
count = mpi_tg->ValidEntries;
|
|
||||||
tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
|
|
||||||
cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
|
|
||||||
tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
|
|
||||||
cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tg_pg4.NumIOCStatusLogInfoTrigger = 0;
|
|
||||||
memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
|
|
||||||
NUM_VALID_ENTRIES * sizeof(
|
|
||||||
MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
||||||
MPI2_IOCSTATUS_MASK;
|
|
||||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
|
||||||
dcprintk(ioc,
|
|
||||||
pr_err(MPT3SAS_FMT
|
|
||||||
"%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
|
|
||||||
ioc->name, __func__, ioc_status));
|
|
||||||
rc = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out:
|
|
||||||
mpt3sas_config_update_driver_trigger_pg0(ioc,
|
|
||||||
MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpt3sas_config_get_volume_handle - returns volume handle for give hidden
|
* mpt3sas_config_get_volume_handle - returns volume handle for give hidden
|
||||||
* raid components
|
* raid components
|
||||||
|
|
|
||||||
|
|
@ -218,12 +218,6 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
|
||||||
case MPI2_FUNCTION_SMP_PASSTHROUGH:
|
case MPI2_FUNCTION_SMP_PASSTHROUGH:
|
||||||
desc = "smp_passthrough";
|
desc = "smp_passthrough";
|
||||||
break;
|
break;
|
||||||
case MPI2_FUNCTION_TOOLBOX:
|
|
||||||
desc = "toolbox";
|
|
||||||
break;
|
|
||||||
case MPI2_FUNCTION_NVME_ENCAPSULATED:
|
|
||||||
desc = "nvme_encapsulated";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!desc)
|
if (!desc)
|
||||||
|
|
@ -541,8 +535,6 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
|
||||||
/* add a log message to indicate the release */
|
/* add a log message to indicate the release */
|
||||||
printk(MPT3SAS_INFO_FMT "%s: Releasing the trace buffer "
|
printk(MPT3SAS_INFO_FMT "%s: Releasing the trace buffer "
|
||||||
"due to adapter reset.", ioc->name, __func__);
|
"due to adapter reset.", ioc->name, __func__);
|
||||||
ioc->htb_rel.buffer_rel_condition =
|
|
||||||
MPT3_DIAG_BUFFER_REL_TRIGGER;
|
|
||||||
mpt3sas_send_diag_release(ioc, i, &issue_reset);
|
mpt3sas_send_diag_release(ioc, i, &issue_reset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -968,8 +960,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
u8 *data;
|
u8 *data;
|
||||||
|
|
||||||
/* ioc determines which port to use */
|
/* ioc determines which port to use */
|
||||||
if (!ioc->multipath_on_hba)
|
smp_request->PhysicalPort = 0xFF;
|
||||||
smp_request->PhysicalPort = 0xFF;
|
|
||||||
if (smp_request->PassthroughFlags &
|
if (smp_request->PassthroughFlags &
|
||||||
MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE)
|
MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE)
|
||||||
data = (u8 *)&smp_request->SGL;
|
data = (u8 *)&smp_request->SGL;
|
||||||
|
|
@ -1072,7 +1063,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
}
|
}
|
||||||
/* drop to default case for posting the request */
|
/* drop to default case for posting the request */
|
||||||
}
|
}
|
||||||
/* fall through */
|
|
||||||
default:
|
default:
|
||||||
ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
|
ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
|
||||||
data_in_dma, data_in_sz);
|
data_in_dma, data_in_sz);
|
||||||
|
|
@ -1098,9 +1088,10 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
ioc->ignore_loginfos = 0;
|
ioc->ignore_loginfos = 0;
|
||||||
}
|
}
|
||||||
if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {
|
if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) {
|
||||||
mpt3sas_check_cmd_timeout(ioc,
|
issue_reset =
|
||||||
ioc->ctl_cmds.status, mpi_request,
|
mpt3sas_base_check_cmd_timeout(ioc,
|
||||||
karg.data_sge_offset, issue_reset);
|
ioc->ctl_cmds.status, mpi_request,
|
||||||
|
karg.data_sge_offset);
|
||||||
goto issue_host_reset;
|
goto issue_host_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1183,13 +1174,13 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
(!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info))))
|
(!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info))))
|
||||||
mpt3sas_scsih_issue_locked_tm(ioc,
|
mpt3sas_scsih_issue_locked_tm(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
||||||
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, smid,
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
pcie_device->reset_timeout,
|
pcie_device->reset_timeout,
|
||||||
MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE);
|
MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE);
|
||||||
else
|
else
|
||||||
mpt3sas_scsih_issue_locked_tm(ioc,
|
mpt3sas_scsih_issue_locked_tm(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
||||||
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, smid, 30,
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30,
|
||||||
MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET);
|
MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET);
|
||||||
} else
|
} else
|
||||||
mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
||||||
|
|
@ -1408,11 +1399,10 @@ _ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
||||||
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT "%s: enter\n", ioc->name,
|
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT "%s: enter\n", ioc->name,
|
||||||
__func__));
|
__func__));
|
||||||
|
|
||||||
ioc->reset_from_user = 1;
|
|
||||||
scsi_block_requests(ioc->shost);
|
scsi_block_requests(ioc->shost);
|
||||||
retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
||||||
scsi_unblock_requests(ioc->shost);
|
scsi_unblock_requests(ioc->shost);
|
||||||
printk(MPT3SAS_INFO_FMT "ioctl: host reset: %s\n",
|
printk(MPT3SAS_INFO_FMT "host reset: %s\n",
|
||||||
ioc->name, ((!retval) ? "SUCCESS" : "FAILED"));
|
ioc->name, ((!retval) ? "SUCCESS" : "FAILED"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1795,9 +1785,6 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
|
||||||
request_data = ioc->diag_buffer[buffer_type];
|
request_data = ioc->diag_buffer[buffer_type];
|
||||||
request_data_sz = diag_register->requested_buffer_size;
|
request_data_sz = diag_register->requested_buffer_size;
|
||||||
ioc->unique_id[buffer_type] = diag_register->unique_id;
|
ioc->unique_id[buffer_type] = diag_register->unique_id;
|
||||||
/* Reset ioc variables used for additional query commands */
|
|
||||||
ioc->reset_from_user = 0;
|
|
||||||
memset(&ioc->htb_rel, 0, sizeof(struct htb_rel_query));
|
|
||||||
ioc->diag_buffer_status[buffer_type] &= MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
|
ioc->diag_buffer_status[buffer_type] &= MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
|
||||||
memcpy(ioc->product_specific[buffer_type],
|
memcpy(ioc->product_specific[buffer_type],
|
||||||
diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS);
|
diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS);
|
||||||
|
|
@ -1854,9 +1841,10 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
|
||||||
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
||||||
|
|
||||||
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
||||||
mpt3sas_check_cmd_timeout(ioc,
|
issue_reset =
|
||||||
ioc->ctl_diag_cmds.status, mpi_request,
|
mpt3sas_base_check_cmd_timeout(ioc,
|
||||||
sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset);
|
ioc->ctl_diag_cmds.status, mpi_request,
|
||||||
|
sizeof(Mpi2DiagBufferPostRequest_t)/4);
|
||||||
goto issue_host_reset;
|
goto issue_host_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1924,6 +1912,8 @@ mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register)
|
||||||
|
|
||||||
printk(MPT3SAS_INFO_FMT "registering trace buffer support\n",
|
printk(MPT3SAS_INFO_FMT "registering trace buffer support\n",
|
||||||
ioc->name);
|
ioc->name);
|
||||||
|
ioc->diag_trigger_master.MasterData =
|
||||||
|
(MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);
|
||||||
diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
|
diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
|
||||||
diag_register.unique_id =
|
diag_register.unique_id =
|
||||||
(ioc->hba_mpi_version_belonged == MPI2_VERSION)?
|
(ioc->hba_mpi_version_belonged == MPI2_VERSION)?
|
||||||
|
|
@ -2240,7 +2230,6 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,
|
||||||
u16 ioc_status;
|
u16 ioc_status;
|
||||||
u32 ioc_state;
|
u32 ioc_state;
|
||||||
int rc;
|
int rc;
|
||||||
u8 reset_needed = 0;
|
|
||||||
|
|
||||||
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT "%s\n", ioc->name,
|
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT "%s\n", ioc->name,
|
||||||
__func__));
|
__func__));
|
||||||
|
|
@ -2292,10 +2281,9 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type,
|
||||||
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
||||||
|
|
||||||
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
||||||
mpt3sas_check_cmd_timeout(ioc,
|
*issue_reset = mpt3sas_base_check_cmd_timeout(ioc,
|
||||||
ioc->ctl_diag_cmds.status, mpi_request,
|
ioc->ctl_diag_cmds.status, mpi_request,
|
||||||
sizeof(Mpi2DiagReleaseRequest_t)/4, reset_needed);
|
sizeof(Mpi2DiagReleaseRequest_t)/4);
|
||||||
*issue_reset = reset_needed;
|
|
||||||
ioc->diag_buffer_status[buffer_type] |=
|
ioc->diag_buffer_status[buffer_type] |=
|
||||||
MPT3_DIAG_BUFFER_IS_RELEASED;
|
MPT3_DIAG_BUFFER_IS_RELEASED;
|
||||||
rc = -EFAULT;
|
rc = -EFAULT;
|
||||||
|
|
@ -2411,7 +2399,6 @@ _ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_IOCTL;
|
|
||||||
rc = mpt3sas_send_diag_release(ioc, buffer_type, &issue_reset);
|
rc = mpt3sas_send_diag_release(ioc, buffer_type, &issue_reset);
|
||||||
|
|
||||||
if (issue_reset)
|
if (issue_reset)
|
||||||
|
|
@ -2568,9 +2555,10 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
||||||
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
MPT3_IOCTL_DEFAULT_TIMEOUT*HZ);
|
||||||
|
|
||||||
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
if (!(ioc->ctl_diag_cmds.status & MPT3_CMD_COMPLETE)) {
|
||||||
mpt3sas_check_cmd_timeout(ioc,
|
issue_reset =
|
||||||
ioc->ctl_diag_cmds.status, mpi_request,
|
mpt3sas_base_check_cmd_timeout(ioc,
|
||||||
sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset);
|
ioc->ctl_diag_cmds.status, mpi_request,
|
||||||
|
sizeof(Mpi2DiagBufferPostRequest_t)/4);
|
||||||
goto issue_host_reset;
|
goto issue_host_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2610,62 +2598,6 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* _ctl_addnl_diag_query - query relevant info associated with diag buffers
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @arg - user space buffer containing ioctl content
|
|
||||||
*
|
|
||||||
* The application will send only unique_id. Driver will
|
|
||||||
* inspect unique_id first, if valid, fill the details related to cause
|
|
||||||
* for diag buffer release.
|
|
||||||
*/
|
|
||||||
static long
|
|
||||||
_ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
|
|
||||||
{
|
|
||||||
struct mpt3_addnl_diag_query karg;
|
|
||||||
u32 buffer_type = 0;
|
|
||||||
|
|
||||||
if (copy_from_user(&karg, arg, sizeof(karg))) {
|
|
||||||
pr_err("%s: failure at %s:%d/%s()!\n",
|
|
||||||
ioc->name, __FILE__, __LINE__, __func__);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT "%s\n", ioc->name,
|
|
||||||
__func__));
|
|
||||||
if (karg.unique_id == 0) {
|
|
||||||
pr_err("%s: %s: unique_id is(0x%08x) \n",
|
|
||||||
ioc->name, __func__, karg.unique_id);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);
|
|
||||||
if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {
|
|
||||||
pr_err("%s: %s: buffer with unique_id(0x%08x) not found\n",
|
|
||||||
ioc->name, __func__, karg.unique_id);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query));
|
|
||||||
if ((ioc->diag_buffer_status[buffer_type] &
|
|
||||||
MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
|
|
||||||
pr_info("%s: %s: buffer_type(0x%02x) is not registered\n",
|
|
||||||
ioc->name, __func__, buffer_type);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((ioc->diag_buffer_status[buffer_type] &
|
|
||||||
MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {
|
|
||||||
pr_err("%s: %s: buffer_type(0x%02x) is not released\n",
|
|
||||||
ioc->name, __func__, buffer_type);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
memcpy(&karg.buffer_rel_condition, &ioc->htb_rel,
|
|
||||||
sizeof(struct htb_rel_query));
|
|
||||||
out:
|
|
||||||
if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {
|
|
||||||
pr_err("%s: %s: unable to write mpt3_addnl_diag_query data @ %p\n",
|
|
||||||
ioc->name, __func__, arg);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
/**
|
/**
|
||||||
|
|
@ -2729,7 +2661,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
||||||
struct MPT3SAS_ADAPTER *ioc;
|
struct MPT3SAS_ADAPTER *ioc;
|
||||||
struct mpt3_ioctl_header ioctl_header;
|
struct mpt3_ioctl_header ioctl_header;
|
||||||
enum block_state state;
|
enum block_state state;
|
||||||
long ret = -ENOIOCTLCMD;
|
long ret = -EINVAL;
|
||||||
|
|
||||||
/* get IOCTL header */
|
/* get IOCTL header */
|
||||||
if (copy_from_user(&ioctl_header, (char __user *)arg,
|
if (copy_from_user(&ioctl_header, (char __user *)arg,
|
||||||
|
|
@ -2845,10 +2777,6 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
|
||||||
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer))
|
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer))
|
||||||
ret = _ctl_diag_read_buffer(ioc, arg);
|
ret = _ctl_diag_read_buffer(ioc, arg);
|
||||||
break;
|
break;
|
||||||
case MPT3ADDNLDIAGQUERY:
|
|
||||||
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_addnl_diag_query))
|
|
||||||
ret = _ctl_addnl_diag_query(ioc, arg);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT
|
dctlprintk(ioc, printk(MPT3SAS_INFO_FMT
|
||||||
"unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
|
"unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
|
||||||
|
|
@ -3663,9 +3591,7 @@ mpt3sas_ctl_tm_sysfs(struct MPT3SAS_ADAPTER *ioc, u8 task_type)
|
||||||
tm_count++;
|
tm_count++;
|
||||||
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
if ((doorbell &
|
if ((doorbell &
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT)
|
||||||
(doorbell &
|
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP )
|
|
||||||
goto fault_in_progress;
|
goto fault_in_progress;
|
||||||
ioc->put_smid_hi_priority(ioc, hpr_smid, 0);
|
ioc->put_smid_hi_priority(ioc, hpr_smid, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -3717,9 +3643,7 @@ mpt3sas_ctl_tm_sysfs(struct MPT3SAS_ADAPTER *ioc, u8 task_type)
|
||||||
tm_count++;
|
tm_count++;
|
||||||
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
if ((doorbell &
|
if ((doorbell &
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
||||||
(doorbell &
|
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) {
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock,
|
spin_unlock_irqrestore(&ioc->sas_device_lock,
|
||||||
flags);
|
flags);
|
||||||
goto fault_in_progress;
|
goto fault_in_progress;
|
||||||
|
|
@ -3775,9 +3699,7 @@ mpt3sas_ctl_tm_sysfs(struct MPT3SAS_ADAPTER *ioc, u8 task_type)
|
||||||
tm_count++;
|
tm_count++;
|
||||||
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
if ((doorbell &
|
if ((doorbell &
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
||||||
(doorbell &
|
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) {
|
|
||||||
spin_unlock_irqrestore(&ioc->pcie_device_lock,
|
spin_unlock_irqrestore(&ioc->pcie_device_lock,
|
||||||
flags);
|
flags);
|
||||||
goto fault_in_progress;
|
goto fault_in_progress;
|
||||||
|
|
@ -3828,9 +3750,7 @@ mpt3sas_ctl_tm_sysfs(struct MPT3SAS_ADAPTER *ioc, u8 task_type)
|
||||||
tm_count++;
|
tm_count++;
|
||||||
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
if ((doorbell &
|
if ((doorbell &
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
||||||
(doorbell &
|
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) {
|
|
||||||
spin_unlock_irqrestore(&ioc->raid_device_lock,
|
spin_unlock_irqrestore(&ioc->raid_device_lock,
|
||||||
flags);
|
flags);
|
||||||
goto fault_in_progress;
|
goto fault_in_progress;
|
||||||
|
|
@ -3901,9 +3821,7 @@ mpt3sas_ctl_tm_sysfs(struct MPT3SAS_ADAPTER *ioc, u8 task_type)
|
||||||
tm_count++;
|
tm_count++;
|
||||||
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
doorbell = mpt3sas_base_get_iocstate(ioc, 0);
|
||||||
if ((doorbell &
|
if ((doorbell &
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT ||
|
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
|
||||||
(doorbell &
|
|
||||||
MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) {
|
|
||||||
scsi_device_put(sdev);
|
scsi_device_put(sdev);
|
||||||
goto fault_in_progress;
|
goto fault_in_progress;
|
||||||
}
|
}
|
||||||
|
|
@ -3960,10 +3878,8 @@ _ctl_task_management_store(struct class_device *cdev, const char *buf,
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
ioc->reset_from_user = 1;
|
|
||||||
scsi_block_requests(ioc->shost);
|
scsi_block_requests(ioc->shost);
|
||||||
printk(MPT3SAS_INFO_FMT
|
printk(MPT3SAS_INFO_FMT "diag reset: %s\n", ioc->name,
|
||||||
"sysfs: diag reset issued: %s\n", ioc->name,
|
|
||||||
((!mpt3sas_base_hard_reset_handler(ioc,
|
((!mpt3sas_base_hard_reset_handler(ioc,
|
||||||
FORCE_BIG_HAMMER)) ? "SUCCESS" : "FAILED"));
|
FORCE_BIG_HAMMER)) ? "SUCCESS" : "FAILED"));
|
||||||
scsi_unblock_requests(ioc->shost);
|
scsi_unblock_requests(ioc->shost);
|
||||||
|
|
@ -3971,10 +3887,8 @@ _ctl_task_management_store(struct class_device *cdev, const char *buf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
ioc->reset_from_user = 1;
|
|
||||||
scsi_block_requests(ioc->shost);
|
scsi_block_requests(ioc->shost);
|
||||||
printk(MPT3SAS_INFO_FMT
|
printk(MPT3SAS_INFO_FMT "message unit reset: %s\n", ioc->name,
|
||||||
"sysfs: message unit reset issued: %s\n", ioc->name,
|
|
||||||
((!mpt3sas_base_hard_reset_handler(ioc,
|
((!mpt3sas_base_hard_reset_handler(ioc,
|
||||||
SOFT_RESET)) ? "SUCCESS" : "FAILED"));
|
SOFT_RESET)) ? "SUCCESS" : "FAILED"));
|
||||||
scsi_unblock_requests(ioc->shost);
|
scsi_unblock_requests(ioc->shost);
|
||||||
|
|
@ -3982,8 +3896,7 @@ _ctl_task_management_store(struct class_device *cdev, const char *buf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
printk(MPT3SAS_INFO_FMT
|
printk(MPT3SAS_INFO_FMT "TASKTYPE_ABORT_TASK:\n", ioc->name);
|
||||||
"sysfs: TASKTYPE_ABORT_TASK :\n", ioc->name);
|
|
||||||
ioc->got_task_abort_from_sysfs = 1;
|
ioc->got_task_abort_from_sysfs = 1;
|
||||||
mpt3sas_ctl_tm_sysfs(ioc,
|
mpt3sas_ctl_tm_sysfs(ioc,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
|
||||||
|
|
@ -3991,22 +3904,20 @@ _ctl_task_management_store(struct class_device *cdev, const char *buf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
printk(MPT3SAS_INFO_FMT
|
printk(MPT3SAS_INFO_FMT "TASKTYPE_TARGET_RESET:\n", ioc->name);
|
||||||
"sysfs: TASKTYPE_TARGET_RESET:\n", ioc->name);
|
|
||||||
mpt3sas_ctl_tm_sysfs(ioc,
|
mpt3sas_ctl_tm_sysfs(ioc,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
|
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
printk(MPT3SAS_INFO_FMT
|
printk(MPT3SAS_INFO_FMT "TASKTYPE_LOGICAL_UNIT_RESET:\n",
|
||||||
"sysfs: TASKTYPE_LOGICAL_UNIT_RESET:\n", ioc->name);
|
ioc->name);
|
||||||
mpt3sas_ctl_tm_sysfs(ioc,
|
mpt3sas_ctl_tm_sysfs(ioc,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET);
|
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
printk(MPT3SAS_INFO_FMT "sysfs: TASKTYPE_ABRT_TASK_SET\n",
|
printk(MPT3SAS_INFO_FMT "TASKTYPE_ABRT_TASK_SET\n", ioc->name);
|
||||||
ioc->name);
|
|
||||||
mpt3sas_ctl_tm_sysfs(ioc,
|
mpt3sas_ctl_tm_sysfs(ioc,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET);
|
MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET);
|
||||||
break;
|
break;
|
||||||
|
|
@ -4395,7 +4306,6 @@ _ctl_host_trace_buffer_enable_store(struct class_device *cdev, const char *buf,
|
||||||
goto out;
|
goto out;
|
||||||
printk(MPT3SAS_INFO_FMT "releasing host trace buffer\n",
|
printk(MPT3SAS_INFO_FMT "releasing host trace buffer\n",
|
||||||
ioc->name);
|
ioc->name);
|
||||||
ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_SYSFS;
|
|
||||||
mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
|
mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
|
||||||
&issue_reset);
|
&issue_reset);
|
||||||
}
|
}
|
||||||
|
|
@ -4462,38 +4372,17 @@ _ctl_diag_trigger_master_store(struct class_device *cdev, const char *buf,
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
struct Scsi_Host *shost = class_to_shost(cdev);
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
||||||
struct SL_WH_MASTER_TRIGGER_T *master_tg;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
bool set = 1;
|
|
||||||
|
|
||||||
rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count);
|
|
||||||
|
|
||||||
if (ioc->supports_trigger_pages) {
|
|
||||||
master_tg = kzalloc(sizeof(struct SL_WH_MASTER_TRIGGER_T),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!master_tg)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(master_tg, buf, rc);
|
|
||||||
if (!master_tg->MasterData)
|
|
||||||
set = 0;
|
|
||||||
if (mpt3sas_config_update_driver_trigger_pg1(ioc, master_tg,
|
|
||||||
set)) {
|
|
||||||
kfree(master_tg);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
||||||
|
rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count);
|
||||||
memset(&ioc->diag_trigger_master, 0,
|
memset(&ioc->diag_trigger_master, 0,
|
||||||
sizeof(struct SL_WH_MASTER_TRIGGER_T));
|
sizeof(struct SL_WH_MASTER_TRIGGER_T));
|
||||||
memcpy(&ioc->diag_trigger_master, buf, rc);
|
memcpy(&ioc->diag_trigger_master, buf, rc);
|
||||||
ioc->diag_trigger_master.MasterData |=
|
ioc->diag_trigger_master.MasterData |=
|
||||||
(MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);
|
(MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);
|
||||||
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
|
|
@ -4551,37 +4440,17 @@ _ctl_diag_trigger_event_store(struct class_device *cdev, const char *buf,
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
struct Scsi_Host *shost = class_to_shost(cdev);
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
||||||
struct SL_WH_EVENT_TRIGGERS_T *event_tg;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
bool set = 1;
|
|
||||||
|
|
||||||
sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count);
|
|
||||||
if (ioc->supports_trigger_pages) {
|
|
||||||
event_tg = kzalloc(sizeof(struct SL_WH_EVENT_TRIGGERS_T),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!event_tg)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(event_tg, buf, sz);
|
|
||||||
if (!event_tg->ValidEntries)
|
|
||||||
set = 0;
|
|
||||||
if (mpt3sas_config_update_driver_trigger_pg2(ioc, event_tg,
|
|
||||||
set)) {
|
|
||||||
kfree(event_tg);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
||||||
|
sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count);
|
||||||
memset(&ioc->diag_trigger_event, 0,
|
memset(&ioc->diag_trigger_event, 0,
|
||||||
sizeof(struct SL_WH_EVENT_TRIGGERS_T));
|
sizeof(struct SL_WH_EVENT_TRIGGERS_T));
|
||||||
memcpy(&ioc->diag_trigger_event, buf, sz);
|
memcpy(&ioc->diag_trigger_event, buf, sz);
|
||||||
if (ioc->diag_trigger_event.ValidEntries > NUM_VALID_ENTRIES)
|
if (ioc->diag_trigger_event.ValidEntries > NUM_VALID_ENTRIES)
|
||||||
ioc->diag_trigger_event.ValidEntries = NUM_VALID_ENTRIES;
|
ioc->diag_trigger_event.ValidEntries = NUM_VALID_ENTRIES;
|
||||||
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
|
|
@ -4639,36 +4508,16 @@ _ctl_diag_trigger_scsi_store(struct class_device *cdev, const char *buf,
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
struct Scsi_Host *shost = class_to_shost(cdev);
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
||||||
struct SL_WH_SCSI_TRIGGERS_T *scsi_tg;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
bool set = 1;
|
|
||||||
|
|
||||||
sz = min(sizeof(struct SL_WH_SCSI_TRIGGERS_T), count);
|
|
||||||
if (ioc->supports_trigger_pages) {
|
|
||||||
scsi_tg = kzalloc(sizeof(struct SL_WH_SCSI_TRIGGERS_T),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!scsi_tg)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(scsi_tg, buf, sz);
|
|
||||||
if (!scsi_tg->ValidEntries)
|
|
||||||
set = 0;
|
|
||||||
if (mpt3sas_config_update_driver_trigger_pg3(ioc, scsi_tg,
|
|
||||||
set)) {
|
|
||||||
kfree(scsi_tg);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
||||||
|
sz = min(sizeof(ioc->diag_trigger_scsi), count);
|
||||||
memset(&ioc->diag_trigger_scsi, 0, sizeof(ioc->diag_trigger_scsi));
|
memset(&ioc->diag_trigger_scsi, 0, sizeof(ioc->diag_trigger_scsi));
|
||||||
memcpy(&ioc->diag_trigger_scsi, buf, sz);
|
memcpy(&ioc->diag_trigger_scsi, buf, sz);
|
||||||
if (ioc->diag_trigger_scsi.ValidEntries > NUM_VALID_ENTRIES)
|
if (ioc->diag_trigger_scsi.ValidEntries > NUM_VALID_ENTRIES)
|
||||||
ioc->diag_trigger_scsi.ValidEntries = NUM_VALID_ENTRIES;
|
ioc->diag_trigger_scsi.ValidEntries = NUM_VALID_ENTRIES;
|
||||||
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
|
|
@ -4727,36 +4576,17 @@ _ctl_diag_trigger_mpi_store(struct class_device *cdev, const char *buf,
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
struct Scsi_Host *shost = class_to_shost(cdev);
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
||||||
struct SL_WH_MPI_TRIGGERS_T *mpi_tg;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
bool set = 1;
|
|
||||||
|
|
||||||
sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count);
|
|
||||||
if (ioc->supports_trigger_pages) {
|
|
||||||
mpi_tg = kzalloc(sizeof(struct SL_WH_MPI_TRIGGERS_T),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!mpi_tg)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(mpi_tg, buf, sz);
|
|
||||||
if (!mpi_tg->ValidEntries)
|
|
||||||
set = 0;
|
|
||||||
if (mpt3sas_config_update_driver_trigger_pg4(ioc, mpi_tg,
|
|
||||||
set)) {
|
|
||||||
kfree(mpi_tg);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
spin_lock_irqsave(&ioc->diag_trigger_lock, flags);
|
||||||
|
sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count);
|
||||||
memset(&ioc->diag_trigger_mpi, 0,
|
memset(&ioc->diag_trigger_mpi, 0,
|
||||||
sizeof(struct SL_WH_EVENT_TRIGGERS_T));
|
sizeof(struct SL_WH_EVENT_TRIGGERS_T));
|
||||||
memcpy(&ioc->diag_trigger_mpi, buf, sz);
|
memcpy(&ioc->diag_trigger_mpi, buf, sz);
|
||||||
if (ioc->diag_trigger_mpi.ValidEntries > NUM_VALID_ENTRIES)
|
if (ioc->diag_trigger_mpi.ValidEntries > NUM_VALID_ENTRIES)
|
||||||
ioc->diag_trigger_mpi.ValidEntries = NUM_VALID_ENTRIES;
|
ioc->diag_trigger_mpi.ValidEntries = NUM_VALID_ENTRIES;
|
||||||
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
spin_unlock_irqrestore(&ioc->diag_trigger_lock, flags);
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
|
|
@ -4798,123 +4628,6 @@ static CLASS_DEVICE_ATTR(drv_support_bitmap, S_IRUGO,
|
||||||
_ctl_drv_support_bitmap_show, NULL);
|
_ctl_drv_support_bitmap_show, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* _ctl_enable_sdev_max_qd_show - display whether enable_sdev_max_qd is
|
|
||||||
* enabled/disabled
|
|
||||||
* @cdev - pointer to embedded class device
|
|
||||||
* @buf - the buffer returned
|
|
||||||
*
|
|
||||||
* A sysfs read/write shost attribute. This attribute is used to set the
|
|
||||||
* targets queue depth to HBA IO queue depth if this attribute is enabled.
|
|
||||||
*/
|
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
|
||||||
static ssize_t
|
|
||||||
_ctl_enable_sdev_max_qd_show(struct device *cdev,
|
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
#else
|
|
||||||
static ssize_t
|
|
||||||
_ctl_enable_sdev_max_qd_show(struct class_device *cdev, char *buf)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", ioc->enable_sdev_max_qd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* _ctl_enable_sdev_max_qd_store - Enable/disable enable_sdev_max_qd
|
|
||||||
* @cdev - pointer to embedded class device
|
|
||||||
* @buf - the buffer returned
|
|
||||||
*
|
|
||||||
* A sysfs read/write shost attribute. This attribute is used to set the
|
|
||||||
* targets queue depth to HBA IO queue depth if this attribute is enabled.
|
|
||||||
* If this attribute is disabled then targets will have default
|
|
||||||
* queue depth.
|
|
||||||
*/
|
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
|
||||||
static ssize_t
|
|
||||||
_ctl_enable_sdev_max_qd_store(struct device *cdev,
|
|
||||||
struct device_attribute *attr, const char *buf, size_t count)
|
|
||||||
#else
|
|
||||||
static ssize_t
|
|
||||||
_ctl_enable_sdev_max_qd_store(struct class_device *cdev, const char *buf,
|
|
||||||
size_t count)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
struct Scsi_Host *shost = class_to_shost(cdev);
|
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_private(shost);
|
|
||||||
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
|
||||||
struct MPT3SAS_TARGET *sas_target_priv_data;
|
|
||||||
int val = 0;
|
|
||||||
struct scsi_device *sdev;
|
|
||||||
struct _raid_device *raid_device;
|
|
||||||
int qdepth;
|
|
||||||
|
|
||||||
if (sscanf(buf, "%d", &val) != 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
switch (val) {
|
|
||||||
case 0:
|
|
||||||
ioc->enable_sdev_max_qd = 0;
|
|
||||||
shost_for_each_device(sdev, ioc->shost) {
|
|
||||||
sas_device_priv_data = sdev->hostdata;
|
|
||||||
if (!sas_device_priv_data)
|
|
||||||
continue;
|
|
||||||
sas_target_priv_data = sas_device_priv_data->sas_target;
|
|
||||||
if (!sas_target_priv_data)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME) {
|
|
||||||
raid_device = mpt3sas_raid_device_find_by_handle(ioc,
|
|
||||||
sas_target_priv_data->handle);
|
|
||||||
|
|
||||||
switch (raid_device->volume_type) {
|
|
||||||
case MPI2_RAID_VOL_TYPE_RAID0:
|
|
||||||
if (raid_device->device_info &
|
|
||||||
MPI2_SAS_DEVICE_INFO_SSP_TARGET)
|
|
||||||
qdepth = MPT3SAS_SAS_QUEUE_DEPTH;
|
|
||||||
else
|
|
||||||
qdepth = MPT3SAS_SATA_QUEUE_DEPTH;
|
|
||||||
break;
|
|
||||||
case MPI2_RAID_VOL_TYPE_RAID1E:
|
|
||||||
case MPI2_RAID_VOL_TYPE_RAID1:
|
|
||||||
case MPI2_RAID_VOL_TYPE_RAID10:
|
|
||||||
case MPI2_RAID_VOL_TYPE_UNKNOWN:
|
|
||||||
default:
|
|
||||||
qdepth = MPT3SAS_RAID_QUEUE_DEPTH;
|
|
||||||
}
|
|
||||||
} else if (sas_target_priv_data->flags &
|
|
||||||
MPT_TARGET_FLAGS_PCIE_DEVICE)
|
|
||||||
qdepth = MPT3SAS_NVME_QUEUE_DEPTH;
|
|
||||||
else
|
|
||||||
qdepth = MPT3SAS_SAS_QUEUE_DEPTH;
|
|
||||||
|
|
||||||
mpt3sas_scsih_change_queue_depth(sdev, qdepth);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ioc->enable_sdev_max_qd = 1;
|
|
||||||
shost_for_each_device(sdev, ioc->shost) {
|
|
||||||
mpt3sas_scsih_change_queue_depth(sdev, shost->can_queue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return strlen(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
|
||||||
static DEVICE_ATTR(enable_sdev_max_qd, S_IRUGO | S_IWUSR,
|
|
||||||
_ctl_enable_sdev_max_qd_show, _ctl_enable_sdev_max_qd_store);
|
|
||||||
#else
|
|
||||||
static CLASS_DEVICE_ATTR(enable_sdev_max_qd, S_IRUGO | S_IWUSR,
|
|
||||||
_ctl_enable_sdev_max_qd_show, _ctl_enable_sdev_max_qd_store);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
|
||||||
struct device_attribute *mpt3sas_host_attrs[] = {
|
struct device_attribute *mpt3sas_host_attrs[] = {
|
||||||
&dev_attr_version_fw,
|
&dev_attr_version_fw,
|
||||||
|
|
@ -4951,7 +4664,6 @@ struct device_attribute *mpt3sas_host_attrs[] = {
|
||||||
&dev_attr_ddio_err_count,
|
&dev_attr_ddio_err_count,
|
||||||
#endif
|
#endif
|
||||||
&dev_attr_drv_support_bitmap,
|
&dev_attr_drv_support_bitmap,
|
||||||
&dev_attr_enable_sdev_max_qd,
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
|
@ -4990,7 +4702,6 @@ struct class_device_attribute *mpt3sas_host_attrs[] = {
|
||||||
&class_device_attr_ddio_err_count,
|
&class_device_attr_ddio_err_count,
|
||||||
#endif
|
#endif
|
||||||
&class_device_attr_drv_support_bitmap,
|
&class_device_attr_drv_support_bitmap,
|
||||||
&class_device_attr_enable_sdev_max_qd,
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,6 @@
|
||||||
struct mpt3_diag_query)
|
struct mpt3_diag_query)
|
||||||
#define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \
|
#define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \
|
||||||
struct mpt3_diag_read_buffer)
|
struct mpt3_diag_read_buffer)
|
||||||
#define MPT3ADDNLDIAGQUERY _IOWR(MPT3_MAGIC_NUMBER, 32, \
|
|
||||||
struct mpt3_addnl_diag_query)
|
|
||||||
|
|
||||||
/* Trace Buffer default UniqueId */
|
/* Trace Buffer default UniqueId */
|
||||||
#define MPT2DIAGBUFFUNIQUEID (0x07075900)
|
#define MPT2DIAGBUFFUNIQUEID (0x07075900)
|
||||||
|
|
@ -442,26 +440,6 @@ struct mpt3_diag_read_buffer {
|
||||||
uint32_t diagnostic_data[1];
|
uint32_t diagnostic_data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct mpt3_addnl_diag_query - diagnostic buffer release reason
|
|
||||||
* @hdr - generic header
|
|
||||||
* @unique_id - unique id associated with this buffer.
|
|
||||||
* @buffer_rel_condition - Release condition ioctl/sysfs/reset
|
|
||||||
* @reserved1
|
|
||||||
* @trigger_type - Master/Event/scsi/MPI
|
|
||||||
* @trigger_info_dwords - Data Correspondig to trigger type
|
|
||||||
* @reserved2
|
|
||||||
*/
|
|
||||||
struct mpt3_addnl_diag_query {
|
|
||||||
struct mpt3_ioctl_header hdr;
|
|
||||||
uint32_t unique_id;
|
|
||||||
uint16_t buffer_rel_condition;
|
|
||||||
uint16_t reserved1;
|
|
||||||
uint32_t trigger_type;
|
|
||||||
uint32_t trigger_info_dwords[2];
|
|
||||||
uint32_t reserved2[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Chunk size to use when doing a FW Download */
|
/* Chunk size to use when doing a FW Download */
|
||||||
#define FW_DL_CHUNK_SIZE 0x4000
|
#define FW_DL_CHUNK_SIZE 0x4000
|
||||||
#endif /* MPT3SAS_CTL_H_INCLUDED */
|
#endif /* MPT3SAS_CTL_H_INCLUDED */
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* This is the Fusion MPT base driver providing common API layer interface
|
|
||||||
* for access to MPT (Message Passing Technology) firmware.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 Broadcom Inc.
|
|
||||||
* (mailto:MPT-FusionLinux.pdl@broadcom.com)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* NO WARRANTY
|
|
||||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
|
||||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
|
||||||
* solely responsible for determining the appropriateness of using and
|
|
||||||
* distributing the Program and assumes all risks associated with its
|
|
||||||
* exercise of rights under this Agreement, including but not limited to
|
|
||||||
* the risks and costs of program errors, damage to or loss of data,
|
|
||||||
* programs or equipment, and unavailability or interruption of operations.
|
|
||||||
|
|
||||||
* DISCLAIMER OF LIABILITY
|
|
||||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
||||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
|
||||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
#include <linux/version.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/compat.h>
|
|
||||||
#include <linux/uio.h>
|
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
|
||||||
#include <scsi/scsi_device.h>
|
|
||||||
#include <scsi/scsi_host.h>
|
|
||||||
|
|
||||||
#include "mpt3sas_base.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
|
||||||
#include <linux/debugfs.h>
|
|
||||||
|
|
||||||
struct dentry *mpt3sas_debugfs_root = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _debugfs_iocdump_read : copy ioc dump from debugfs buffer
|
|
||||||
*/
|
|
||||||
static ssize_t
|
|
||||||
_debugfs_iocdump_read(struct file *filp, char __user *ubuf, size_t cnt,
|
|
||||||
loff_t *ppos)
|
|
||||||
|
|
||||||
{
|
|
||||||
struct mpt3sas_debugfs_buffer *debug = filp->private_data;
|
|
||||||
|
|
||||||
if (!debug || !debug->buf)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return simple_read_from_buffer(ubuf, cnt, ppos, debug->buf, debug->len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _debugfs_iocdump_open : open the ioc_dump debugfs attribute file
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_debugfs_iocdump_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct MPT3SAS_ADAPTER *ioc = inode->i_private;
|
|
||||||
struct mpt3sas_debugfs_buffer *debug;
|
|
||||||
|
|
||||||
debug = kzalloc(sizeof(struct mpt3sas_debugfs_buffer), GFP_KERNEL);
|
|
||||||
if (!debug)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
debug->buf = (void *)ioc;
|
|
||||||
debug->len = sizeof(struct MPT3SAS_ADAPTER);
|
|
||||||
file->private_data = debug;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* _debugfs_iocdump_release : release the ioc_dump debugfs attribute
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
_debugfs_iocdump_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct mpt3sas_debugfs_buffer *debug = file->private_data;
|
|
||||||
|
|
||||||
if (!debug)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
file->private_data = NULL;
|
|
||||||
kfree(debug);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations mpt3sas_debugfs_iocdump_fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.open = _debugfs_iocdump_open,
|
|
||||||
.read = _debugfs_iocdump_read,
|
|
||||||
.release = _debugfs_iocdump_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mpt3sas_init_debugfs : Create debugfs root for mpt3sas driver
|
|
||||||
*/
|
|
||||||
void mpt3sas_init_debugfs(void)
|
|
||||||
{
|
|
||||||
mpt3sas_debugfs_root = debugfs_create_dir("mpt3sas", NULL);
|
|
||||||
if (!mpt3sas_debugfs_root)
|
|
||||||
pr_info("mpt3sas: Cannot create debugfs root\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mpt3sas_exit_debugfs : Remove debugfs root for mpt3sas driver
|
|
||||||
*/
|
|
||||||
void mpt3sas_exit_debugfs(void)
|
|
||||||
{
|
|
||||||
if (mpt3sas_debugfs_root)
|
|
||||||
debugfs_remove_recursive(mpt3sas_debugfs_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mpt3sas_setup_debugfs : Setup debugfs per HBA adapter
|
|
||||||
* ioc: MPT3SAS_ADAPTER object
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc)
|
|
||||||
{
|
|
||||||
char name[64];
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "scsi_host%d", ioc->shost->host_no);
|
|
||||||
if (!ioc->debugfs_root) {
|
|
||||||
ioc->debugfs_root =
|
|
||||||
debugfs_create_dir(name, mpt3sas_debugfs_root);
|
|
||||||
if (!ioc->debugfs_root) {
|
|
||||||
dev_err(&ioc->pdev->dev,
|
|
||||||
"Cannot create per adapter debugfs directory\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "ioc_dump");
|
|
||||||
ioc->ioc_dump = debugfs_create_file(name, S_IRUGO,
|
|
||||||
ioc->debugfs_root, ioc, &mpt3sas_debugfs_iocdump_fops);
|
|
||||||
if (!ioc->ioc_dump) {
|
|
||||||
dev_err(&ioc->pdev->dev,
|
|
||||||
"Cannot create ioc_dump debugfs file\n");
|
|
||||||
debugfs_remove(ioc->debugfs_root);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "host_recovery");
|
|
||||||
debugfs_create_u8(name, S_IRUGO, ioc->debugfs_root, &ioc->shost_recovery);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mpt3sas_destroy_debugfs : Destroy debugfs per HBA adapter
|
|
||||||
* ioc: MPT3SAS_ADAPTER object
|
|
||||||
*/
|
|
||||||
void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc)
|
|
||||||
{
|
|
||||||
if (ioc->debugfs_root)
|
|
||||||
debugfs_remove_recursive(ioc->debugfs_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void mpt3sas_init_debugfs(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void mpt3sas_exit_debugfs(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void mpt3sas_setup_debugfs(struct megasas_instance *instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void mpt3sas_destroy_debugfs(struct megasas_instance *instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /*CONFIG_DEBUG_FS*/
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -132,26 +132,6 @@ _transport_sas_node_find_by_sas_phy(struct MPT3SAS_ADAPTER *ioc,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to
|
|
||||||
* @phy - sas_phy object
|
|
||||||
*
|
|
||||||
* Return Port number
|
|
||||||
*/
|
|
||||||
static inline u8
|
|
||||||
_transport_get_port_id_by_sas_phy(struct sas_phy *phy)
|
|
||||||
{
|
|
||||||
u8 port_id = 0xFF;
|
|
||||||
#if defined(SAS_PHY_HOSTDATA)
|
|
||||||
struct hba_port *port = phy->hostdata;
|
|
||||||
if (port)
|
|
||||||
port_id = port->port_id;
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
#endif
|
|
||||||
return port_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_transport_find_parent_node(struct MPT3SAS_ADAPTER *ioc,
|
_transport_find_parent_node(struct MPT3SAS_ADAPTER *ioc,
|
||||||
struct sas_phy *phy)
|
struct sas_phy *phy)
|
||||||
|
|
@ -179,49 +159,6 @@ _transport_find_parent_node(struct MPT3SAS_ADAPTER *ioc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* _transport_get_port_id_by_rphy - Get Port number from rphy object
|
|
||||||
* @ioc: per adapter object
|
|
||||||
* @rphy: sas_rphy object
|
|
||||||
*
|
|
||||||
* Returns Port number.
|
|
||||||
*/
|
|
||||||
u8
|
|
||||||
_transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER *ioc,
|
|
||||||
struct sas_rphy *rphy)
|
|
||||||
{
|
|
||||||
struct _sas_node *sas_expander;
|
|
||||||
struct _sas_device *sas_device;
|
|
||||||
unsigned long flags;
|
|
||||||
u8 port_id = 0xFF;
|
|
||||||
|
|
||||||
if (!rphy)
|
|
||||||
return port_id;
|
|
||||||
|
|
||||||
if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
|
|
||||||
rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) {
|
|
||||||
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
|
||||||
list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
|
|
||||||
if (sas_expander->rphy == rphy) {
|
|
||||||
port_id = sas_expander->port->port_id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
|
|
||||||
} else if (rphy->identify.device_type == SAS_END_DEVICE) {
|
|
||||||
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
||||||
sas_device = __mpt3sas_get_sdev_by_addr_and_rphy(ioc,
|
|
||||||
rphy->identify.sas_address, rphy);
|
|
||||||
if (sas_device) {
|
|
||||||
port_id = sas_device->port->port_id;
|
|
||||||
sas_device_put(sas_device);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return port_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _transport_convert_phy_link_rate -
|
* _transport_convert_phy_link_rate -
|
||||||
* @link_rate: link rate returned from mpt firmware
|
* @link_rate: link rate returned from mpt firmware
|
||||||
|
|
@ -440,7 +377,7 @@ struct rep_manu_reply {
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
|
_transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
|
||||||
u64 sas_address, struct sas_expander_device *edev, u8 port_id)
|
u64 sas_address, struct sas_expander_device *edev)
|
||||||
{
|
{
|
||||||
Mpi2SmpPassthroughRequest_t *mpi_request;
|
Mpi2SmpPassthroughRequest_t *mpi_request;
|
||||||
Mpi2SmpPassthroughReply_t *mpi_reply;
|
Mpi2SmpPassthroughReply_t *mpi_reply;
|
||||||
|
|
@ -511,7 +448,7 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
||||||
mpi_request->PhysicalPort = port_id;
|
mpi_request->PhysicalPort = 0xFF;
|
||||||
mpi_request->SASAddress = cpu_to_le64(sas_address);
|
mpi_request->SASAddress = cpu_to_le64(sas_address);
|
||||||
mpi_request->RequestDataLength = cpu_to_le16(data_out_sz);
|
mpi_request->RequestDataLength = cpu_to_le16(data_out_sz);
|
||||||
psge = &mpi_request->SGL;
|
psge = &mpi_request->SGL;
|
||||||
|
|
@ -803,7 +740,6 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
#if defined(MPT_WIDE_PORT_API)
|
#if defined(MPT_WIDE_PORT_API)
|
||||||
struct sas_port *port;
|
struct sas_port *port;
|
||||||
#endif
|
#endif
|
||||||
struct virtual_phy *vphy = NULL;
|
|
||||||
|
|
||||||
if (!hba_port) {
|
if (!hba_port) {
|
||||||
printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n",
|
||||||
|
|
@ -857,21 +793,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
continue;
|
continue;
|
||||||
list_add_tail(&sas_node->phy[i].port_siblings,
|
list_add_tail(&sas_node->phy[i].port_siblings,
|
||||||
&mpt3sas_port->phy_list);
|
&mpt3sas_port->phy_list);
|
||||||
mpt3sas_port->num_phys++;
|
|
||||||
if (sas_node->handle <= ioc->sas_hba.num_phys) {
|
if (sas_node->handle <= ioc->sas_hba.num_phys) {
|
||||||
if (!sas_node->phy[i].hba_vphy) {
|
hba_port->phy_mask |= (1 << i);
|
||||||
hba_port->phy_mask |= (1 << i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vphy = mpt3sas_get_vphy_by_phy(ioc, hba_port, i);
|
|
||||||
if (!vphy) {
|
|
||||||
printk(MPT3SAS_ERR_FMT
|
|
||||||
"failure at %s:%d/%s()!\n",
|
|
||||||
ioc->name, __FILE__, __LINE__, __func__);
|
|
||||||
goto out_fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mpt3sas_port->num_phys++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mpt3sas_port->num_phys) {
|
if (!mpt3sas_port->num_phys) {
|
||||||
|
|
@ -922,14 +847,8 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
|
if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
|
||||||
rphy = sas_end_device_alloc(port);
|
rphy = sas_end_device_alloc(port);
|
||||||
sas_device->rphy=rphy;
|
sas_device->rphy=rphy;
|
||||||
if (sas_node->handle <= ioc->sas_hba.num_phys) {
|
if (sas_node->handle <= ioc->sas_hba.num_phys)
|
||||||
if (!vphy)
|
hba_port->sas_address = sas_device->sas_address;
|
||||||
hba_port->sas_address =
|
|
||||||
sas_device->sas_address;
|
|
||||||
else
|
|
||||||
vphy->sas_address =
|
|
||||||
sas_device->sas_address;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
rphy = sas_expander_alloc(port,
|
rphy = sas_expander_alloc(port,
|
||||||
mpt3sas_port->remote_identify.device_type);
|
mpt3sas_port->remote_identify.device_type);
|
||||||
|
|
@ -957,12 +876,11 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
sas_device->pend_sas_rphy_add = 0;
|
sas_device->pend_sas_rphy_add = 0;
|
||||||
sas_device_put(sas_device);
|
sas_device_put(sas_device);
|
||||||
}
|
}
|
||||||
|
if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
|
||||||
dev_printk(KERN_INFO, &rphy->dev,
|
dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), "
|
||||||
"%s: added: handle(0x%04x), sas_addr(0x%016llx)\n",
|
"sas_addr(0x%016llx)\n", handle,
|
||||||
__func__, handle, (unsigned long long)
|
(unsigned long long)
|
||||||
mpt3sas_port->remote_identify.sas_address);
|
mpt3sas_port->remote_identify.sas_address);
|
||||||
|
|
||||||
mpt3sas_port->rphy = rphy;
|
mpt3sas_port->rphy = rphy;
|
||||||
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
spin_lock_irqsave(&ioc->sas_node_lock, flags);
|
||||||
list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list);
|
list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list);
|
||||||
|
|
@ -976,7 +894,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
|
MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
|
||||||
_transport_expander_report_manufacture(ioc,
|
_transport_expander_report_manufacture(ioc,
|
||||||
mpt3sas_port->remote_identify.sas_address,
|
mpt3sas_port->remote_identify.sas_address,
|
||||||
rphy_to_expander_device(rphy), hba_port->port_id);
|
rphy_to_expander_device(rphy));
|
||||||
#endif
|
#endif
|
||||||
return mpt3sas_port;
|
return mpt3sas_port;
|
||||||
|
|
||||||
|
|
@ -1014,7 +932,6 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
||||||
struct _sas_phy *mpt3sas_phy, *next_phy;
|
struct _sas_phy *mpt3sas_phy, *next_phy;
|
||||||
#endif
|
#endif
|
||||||
struct hba_port *hba_port, *hba_port_next=NULL;
|
struct hba_port *hba_port, *hba_port_next=NULL;
|
||||||
struct virtual_phy *vphy, *vphy_next=NULL;
|
|
||||||
|
|
||||||
if (!port)
|
if (!port)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1045,52 +962,17 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
||||||
|
|
||||||
if ((sas_node->handle <= ioc->sas_hba.num_phys) &&
|
if ((sas_node->handle <= ioc->sas_hba.num_phys) &&
|
||||||
(ioc->multipath_on_hba)) {
|
(ioc->multipath_on_hba)) {
|
||||||
|
|
||||||
if (port->vphys_mask) {
|
|
||||||
list_for_each_entry_safe(vphy, vphy_next,
|
|
||||||
&port->vphys_list, list) {
|
|
||||||
if (vphy->sas_address != sas_address)
|
|
||||||
continue;
|
|
||||||
printk(MPT3SAS_INFO_FMT
|
|
||||||
"remove vphy entry: %p of port:%p,from %d"
|
|
||||||
" port's vphys list\n", ioc->name,
|
|
||||||
vphy, port, port->port_id);
|
|
||||||
port->vphys_mask &= ~vphy->phy_mask;
|
|
||||||
list_del(&vphy->list);
|
|
||||||
kfree(vphy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!port->vphys_mask && !port->sas_address) {
|
|
||||||
printk(MPT3SAS_INFO_FMT
|
|
||||||
"remove hba_port entry: %p port: %d from"
|
|
||||||
" hba_port list\n", ioc->name,
|
|
||||||
port, port->port_id);
|
|
||||||
list_del(&port->list);
|
|
||||||
kfree(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(hba_port, hba_port_next,
|
list_for_each_entry_safe(hba_port, hba_port_next,
|
||||||
&ioc->port_table_list, list) {
|
&ioc->port_table_list, list) {
|
||||||
if (hba_port != port)
|
if (hba_port != port)
|
||||||
continue;
|
continue;
|
||||||
if (hba_port->sas_address != sas_address)
|
if (hba_port->sas_address != sas_address)
|
||||||
continue;
|
continue;
|
||||||
if (!port->vphys_mask) {
|
printk(MPT3SAS_INFO_FMT "remove hba_port entry: %p"
|
||||||
printk(MPT3SAS_INFO_FMT
|
" port: %d from hba_port list\n", ioc->name,
|
||||||
"remove hba_port entry: %p port: %d from"
|
hba_port, hba_port->port_id);
|
||||||
" hba_port list\n", ioc->name,
|
list_del(&hba_port->list);
|
||||||
hba_port, hba_port->port_id);
|
kfree(hba_port);
|
||||||
list_del(&hba_port->list);
|
|
||||||
kfree(hba_port);
|
|
||||||
} else {
|
|
||||||
printk(MPT3SAS_INFO_FMT
|
|
||||||
"clearing sas_address from hba_port"
|
|
||||||
" entry: %p port: %d from hba_port list\n",
|
|
||||||
ioc->name, hba_port, hba_port->port_id);
|
|
||||||
port->sas_address = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1118,8 +1000,6 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
||||||
}
|
}
|
||||||
if(!ioc->remove_host)
|
if(!ioc->remove_host)
|
||||||
sas_port_delete(mpt3sas_port->port);
|
sas_port_delete(mpt3sas_port->port);
|
||||||
printk(MPT3SAS_INFO_FMT "%s: removed: sas_addr(0x%016llx)\n",
|
|
||||||
ioc->name, __func__, (unsigned long long)sas_address);
|
|
||||||
#else
|
#else
|
||||||
if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
|
if ((ioc->logging_level & MPT_DEBUG_TRANSPORT))
|
||||||
dev_printk(KERN_INFO, &mpt3sas_port->rphy->dev,
|
dev_printk(KERN_INFO, &mpt3sas_port->rphy->dev,
|
||||||
|
|
@ -1127,8 +1007,6 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address,
|
||||||
(unsigned long long)sas_address);
|
(unsigned long long)sas_address);
|
||||||
if(!ioc->remove_host)
|
if(!ioc->remove_host)
|
||||||
sas_rphy_delete(mpt3sas_port->rphy);
|
sas_rphy_delete(mpt3sas_port->rphy);
|
||||||
printk(MPT3SAS_INFO_FMT "%s: removed: sas_addr(0x%016llx)\n",
|
|
||||||
ioc->name, __func__, (unsigned long long)sas_address);
|
|
||||||
#endif
|
#endif
|
||||||
kfree(mpt3sas_port);
|
kfree(mpt3sas_port);
|
||||||
}
|
}
|
||||||
|
|
@ -1476,7 +1354,7 @@ _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
||||||
mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
|
mpi_request->PhysicalPort = 0xFF;
|
||||||
mpi_request->VF_ID = 0; /* TODO */
|
mpi_request->VF_ID = 0; /* TODO */
|
||||||
mpi_request->VP_ID = 0;
|
mpi_request->VP_ID = 0;
|
||||||
mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
|
mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
|
||||||
|
|
@ -1768,7 +1646,7 @@ _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
||||||
mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy);
|
mpi_request->PhysicalPort = 0xFF;
|
||||||
mpi_request->VF_ID = 0; /* TODO */
|
mpi_request->VF_ID = 0; /* TODO */
|
||||||
mpi_request->VP_ID = 0;
|
mpi_request->VP_ID = 0;
|
||||||
mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
|
mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address);
|
||||||
|
|
@ -2263,7 +2141,7 @@ _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
|
||||||
|
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
||||||
mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy);
|
mpi_request->PhysicalPort = 0xFF;
|
||||||
mpi_request->SASAddress = (rphy) ?
|
mpi_request->SASAddress = (rphy) ?
|
||||||
cpu_to_le64(rphy->identify.sas_address) :
|
cpu_to_le64(rphy->identify.sas_address) :
|
||||||
cpu_to_le64(ioc->sas_hba.sas_address);
|
cpu_to_le64(ioc->sas_hba.sas_address);
|
||||||
|
|
@ -2491,7 +2369,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
|
||||||
|
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
|
||||||
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
|
||||||
mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy);
|
mpi_request->PhysicalPort = 0xFF;
|
||||||
mpi_request->SASAddress = (rphy) ?
|
mpi_request->SASAddress = (rphy) ?
|
||||||
cpu_to_le64(rphy->identify.sas_address) :
|
cpu_to_le64(rphy->identify.sas_address) :
|
||||||
cpu_to_le64(ioc->sas_hba.sas_address);
|
cpu_to_le64(ioc->sas_hba.sas_address);
|
||||||
|
|
|
||||||
|
|
@ -134,36 +134,8 @@ mpt3sas_process_trigger_data(struct MPT3SAS_ADAPTER *ioc,
|
||||||
&issue_reset);
|
&issue_reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_TRIGGER;
|
|
||||||
if (event_data) {
|
|
||||||
ioc->htb_rel.trigger_type = event_data->trigger_type;
|
|
||||||
switch (event_data->trigger_type) {
|
|
||||||
case MPT3SAS_TRIGGER_SCSI:
|
|
||||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
|
||||||
&event_data->u.scsi,
|
|
||||||
sizeof(struct SL_WH_SCSI_TRIGGER_T));
|
|
||||||
break;
|
|
||||||
case MPT3SAS_TRIGGER_MPI:
|
|
||||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
|
||||||
&event_data->u.mpi,
|
|
||||||
sizeof(struct SL_WH_MPI_TRIGGER_T));
|
|
||||||
break;
|
|
||||||
case MPT3SAS_TRIGGER_MASTER:
|
|
||||||
ioc->htb_rel.trigger_info_dwords[0] =
|
|
||||||
event_data->u.master.MasterData;
|
|
||||||
break;
|
|
||||||
case MPT3SAS_TRIGGER_EVENT:
|
|
||||||
memcpy(&ioc->htb_rel.trigger_info_dwords,
|
|
||||||
&event_data->u.event,
|
|
||||||
sizeof(struct SL_WH_EVENT_TRIGGER_T));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_err("%s: %d - Is not a valid Trigger type\n",
|
|
||||||
ioc->name, event_data->trigger_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_mpt3sas_raise_sigio(ioc, event_data);
|
_mpt3sas_raise_sigio(ioc, event_data);
|
||||||
|
|
||||||
dTriggerDiagPrintk(ioc, printk(MPT3SAS_INFO_FMT "%s: exit\n", ioc->name,
|
dTriggerDiagPrintk(ioc, printk(MPT3SAS_INFO_FMT "%s: exit\n", ioc->name,
|
||||||
__func__));
|
__func__));
|
||||||
}
|
}
|
||||||
|
|
@ -228,15 +200,11 @@ mpt3sas_trigger_master(struct MPT3SAS_ADAPTER *ioc, u32 trigger_bitmask)
|
||||||
memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
|
memset(&event_data, 0, sizeof(struct SL_WH_TRIGGERS_EVENT_DATA_T));
|
||||||
event_data.trigger_type = MPT3SAS_TRIGGER_MASTER;
|
event_data.trigger_type = MPT3SAS_TRIGGER_MASTER;
|
||||||
event_data.u.master.MasterData = trigger_bitmask;
|
event_data.u.master.MasterData = trigger_bitmask;
|
||||||
|
|
||||||
if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
|
if (trigger_bitmask & MASTER_TRIGGER_FW_FAULT ||
|
||||||
trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET) {
|
trigger_bitmask & MASTER_TRIGGER_ADAPTER_RESET)
|
||||||
ioc->htb_rel.trigger_type = MPT3SAS_TRIGGER_MASTER;
|
|
||||||
ioc->htb_rel.trigger_info_dwords[0] = trigger_bitmask;
|
|
||||||
if (ioc->reset_from_user)
|
|
||||||
ioc->htb_rel.trigger_info_dwords[1] =
|
|
||||||
MPT_DIAG_RESET_ISSUED_BY_USER;
|
|
||||||
_mpt3sas_raise_sigio(ioc, &event_data);
|
_mpt3sas_raise_sigio(ioc, &event_data);
|
||||||
} else
|
else
|
||||||
mpt3sas_send_trigger_data_event(ioc, &event_data);
|
mpt3sas_send_trigger_data_event(ioc, &event_data);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the Fusion MPT base driver providing common API layer interface
|
|
||||||
* to store diag trigger values into persistent driver triggers pages
|
|
||||||
* for MPT (Message Passing Technology) based
|
|
||||||
* controllers
|
|
||||||
*
|
|
||||||
* This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h
|
|
||||||
* Copyright (C) 2013-2020 LSI Corporation
|
|
||||||
* Copyright (C) 2013-2020 Avago Technologies
|
|
||||||
* Copyright (C) 2013-2020 Broadcom Inc.
|
|
||||||
* (mailto:MPT-FusionLinux.pdl@broadcom.com)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* NO WARRANTY
|
|
||||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
|
||||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
|
||||||
* solely responsible for determining the appropriateness of using and
|
|
||||||
* distributing the Program and assumes all risks associated with its
|
|
||||||
* exercise of rights under this Agreement, including but not limited to
|
|
||||||
* the risks and costs of program errors, damage to or loss of data,
|
|
||||||
* programs or equipment, and unavailability or interruption of operations.
|
|
||||||
|
|
||||||
* DISCLAIMER OF LIABILITY
|
|
||||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
||||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
|
||||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
||||||
* USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mpi/mpi2_cnfg.h"
|
|
||||||
|
|
||||||
#ifndef MPI2_TRIGGER_PAGES_H
|
|
||||||
#define MPI2_TRIGGER_PAGES_H
|
|
||||||
|
|
||||||
#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER (0xE0)
|
|
||||||
|
|
||||||
#define MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION (0x01)
|
|
||||||
typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_0
|
|
||||||
{
|
|
||||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
|
||||||
U16 TriggerFlags; /* 0x08 */
|
|
||||||
U16 Reserved0xA; /* 0x0A */
|
|
||||||
U32 Reserved0xC[61]; /* 0x0C */
|
|
||||||
} MPI26_CONFIG_PAGE_DRIVER_TIGGER_0,
|
|
||||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_DRIVER_TIGGER_0,
|
|
||||||
Mpi26DriverTriggerPage0_t, MPI2_POINTER pMpi26DriverTriggerPage0_t;
|
|
||||||
|
|
||||||
/* Trigger Flags */
|
|
||||||
#define MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID (0x0001)
|
|
||||||
#define MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID (0x0002)
|
|
||||||
#define MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID (0x0004)
|
|
||||||
#define MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID (0x0008)
|
|
||||||
|
|
||||||
|
|
||||||
#define MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION (0x01)
|
|
||||||
typedef struct _MPI26_DRIVER_MASTER_TIGGER_ENTRY
|
|
||||||
{
|
|
||||||
U32 MasterTriggerFlags;
|
|
||||||
} MPI26_DRIVER_MASTER_TIGGER_ENTRY, MPI2_POINTER PTR_MPI26_DRIVER_MASTER_TIGGER_ENTRY;
|
|
||||||
|
|
||||||
#define MPI26_MAX_MASTER_TRIGGERS (1)
|
|
||||||
typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_1
|
|
||||||
{
|
|
||||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
|
||||||
U16 NumMasterTrigger; /* 0x08 */
|
|
||||||
U16 Reserved0xA; /* 0x0A */
|
|
||||||
MPI26_DRIVER_MASTER_TIGGER_ENTRY MasterTriggers[MPI26_MAX_MASTER_TRIGGERS]; /* 0x0C */
|
|
||||||
} MPI26_CONFIG_PAGE_DRIVER_TIGGER_1,
|
|
||||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_DRIVER_TIGGER_1,
|
|
||||||
Mpi26DriverTriggerPage1_t, MPI2_POINTER pMpi26DriverTriggerPage1_t;
|
|
||||||
|
|
||||||
/* Master Trigger Flags */
|
|
||||||
#define MPI26_DRIVER_TRIGGER1_FLAG_FW_FAULT (0x00000001)
|
|
||||||
#define MPI26_DRIVER_TRIGGER1_FLAG_DIAG_RESET (0x00000002)
|
|
||||||
#define MPI26_DRIVER_TRIGGER1_FLAG_TASK_MGMT (0x00000004)
|
|
||||||
#define MPI26_DRIVER_TRIGGER1_FLAG_DEVICE_REMOVAL (0x00000008)
|
|
||||||
|
|
||||||
|
|
||||||
#define MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION (0x01)
|
|
||||||
typedef struct _MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY
|
|
||||||
{
|
|
||||||
U16 MPIEventCode; /* 0x00 */
|
|
||||||
U16 MPIEventCodeSpecific; /* 0x02 */
|
|
||||||
} MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY, MPI2_POINTER PTR_MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY;
|
|
||||||
|
|
||||||
#define MPI26_MAX_MPI_EVENT_TRIGGERS (20)
|
|
||||||
typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_2
|
|
||||||
{
|
|
||||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
|
||||||
U16 NumMPIEventTrigger; /* 0x08 */
|
|
||||||
U16 Reserved0xA; /* 0x0A */
|
|
||||||
MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY MPIEventTriggers[MPI26_MAX_MPI_EVENT_TRIGGERS]; /* 0x0C */
|
|
||||||
} MPI26_CONFIG_PAGE_DRIVER_TIGGER_2,
|
|
||||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_DRIVER_TIGGER_2,
|
|
||||||
Mpi26DriverTriggerPage2_t, MPI2_POINTER pMpi26DriverTriggerPage2_t;
|
|
||||||
|
|
||||||
|
|
||||||
#define MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION (0x01)
|
|
||||||
typedef struct _MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY
|
|
||||||
{
|
|
||||||
U8 ASCQ; /* 0x00 */
|
|
||||||
U8 ASC; /* 0x01 */
|
|
||||||
U8 SenseKey; /* 0x02 */
|
|
||||||
U8 Reserved; /* 0x03 */
|
|
||||||
} MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY, MPI2_POINTER PTR_MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY;
|
|
||||||
|
|
||||||
#define MPI26_MAX_SCSI_SENSE_TRIGGERS (20)
|
|
||||||
typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_3
|
|
||||||
{
|
|
||||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
|
||||||
U16 NumSCSISenseTrigger; /* 0x08 */
|
|
||||||
U16 Reserved0xA; /* 0x0A */
|
|
||||||
MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY SCSISenseTriggers[MPI26_MAX_SCSI_SENSE_TRIGGERS]; /* 0x0C */
|
|
||||||
} MPI26_CONFIG_PAGE_DRIVER_TIGGER_3,
|
|
||||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_DRIVER_TIGGER_3,
|
|
||||||
Mpi26DriverTriggerPage3_t, MPI2_POINTER pMpi26DriverTriggerPage3_t;
|
|
||||||
|
|
||||||
#define MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION (0x01)
|
|
||||||
typedef struct _MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY
|
|
||||||
{
|
|
||||||
U16 IOCStatus; /* 0x00 */
|
|
||||||
U16 Reserved; /* 0x02 */
|
|
||||||
U32 LogInfo; /* 0x04 */
|
|
||||||
} MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY, MPI2_POINTER PTR_MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY;
|
|
||||||
|
|
||||||
#define MPI26_MAX_LOGINFO_TRIGGERS (20)
|
|
||||||
typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_4
|
|
||||||
{
|
|
||||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
|
||||||
U16 NumIOCStatusLogInfoTrigger; /* 0x08 */
|
|
||||||
U16 Reserved0xA; /* 0x0A */
|
|
||||||
MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY IOCStatusLoginfoTriggers[MPI26_MAX_LOGINFO_TRIGGERS]; /* 0x0C */
|
|
||||||
} MPI26_CONFIG_PAGE_DRIVER_TIGGER_4,
|
|
||||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_DRIVER_TIGGER_4,
|
|
||||||
Mpi26DriverTriggerPage4_t, MPI2_POINTER pMpi26DriverTriggerPage4_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# DISCLAIMER OF LIABILITY
|
|
||||||
# THIS IS SAMPLE SCRIPT.
|
|
||||||
# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
|
||||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
|
||||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
||||||
# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
|
||||||
# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
|
|
||||||
|
|
||||||
clear
|
|
||||||
CWD=`pwd`;
|
|
||||||
scsi_host="/sys/class/scsi_host"
|
|
||||||
cd ${scsi_host}
|
|
||||||
subfolders=`ls -1`
|
|
||||||
for i in ${subfolders}; do
|
|
||||||
cd ${i};
|
|
||||||
if [ `cat proc_name` == "mpt3sas" ]; then
|
|
||||||
reset_count=`cat ioc_reset_count`
|
|
||||||
{
|
|
||||||
while true; do
|
|
||||||
if [[ `cat /sys/kernel/debug/mpt3sas/scsi_${i}/host_recovery` == 1 && `cat ioc_reset_count` == $reset_count ]]; then
|
|
||||||
date_str=$(date +'%y-%m-%d-%H-%M-%S')
|
|
||||||
file_name=${i}-iocdump-${date_str};
|
|
||||||
echo "==== host reset on ${i} is observed at ${date_str}, hence copied the ioc dump to file ${file_name} ===="
|
|
||||||
cat /sys/kernel/debug/mpt3sas/scsi_${i}/ioc_dump > ${CWD}/$file_name;
|
|
||||||
reset_count=`expr $reset_count + 1`;
|
|
||||||
fi;
|
|
||||||
sleep 1;
|
|
||||||
done;
|
|
||||||
} &
|
|
||||||
fi;
|
|
||||||
cd ${scsi_host}
|
|
||||||
done;
|
|
||||||
|
|
||||||
while true; do sleep 300; done
|
|
||||||
|
|
||||||
echo -e \\n
|
|
||||||
|
|
@ -3293,7 +3293,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
blk_pm_runtime_init(sdp->request_queue, dev);
|
blk_pm_runtime_init(sdp->request_queue, dev);
|
||||||
device_add_disk(dev, gd, NULL);
|
device_add_disk(dev, gd);
|
||||||
if (sdkp->capacity)
|
if (sdkp->capacity)
|
||||||
sd_dif_config_host(sdkp);
|
sd_dif_config_host(sdkp);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
ccflags-y += -I.
|
ccflags-y += -I.
|
||||||
obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o
|
obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o
|
||||||
smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o smartpqi_kernel_compat.o
|
smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* driver for Microchip PQI-based storage controllers
|
* driver for Microsemi PQI-based storage controllers
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
* Copyright (c) 2016-2017 Microsemi Corporation
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
* Copyright (c) 2016 PMC-Sierra, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -13,18 +12,15 @@
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
* Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||||
|
|
||||||
#if !defined(_SMARTPQI_H)
|
#if !defined(_SMARTPQI_H)
|
||||||
#define _SMARTPQI_H
|
#define _SMARTPQI_H
|
||||||
|
|
||||||
#define TORTUGA 0
|
|
||||||
|
|
||||||
#include <scsi/scsi_host.h>
|
|
||||||
#include <linux/bsg-lib.h>
|
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
#define PQI_DEVICE_SIGNATURE "PQI DREG"
|
#define PQI_DEVICE_SIGNATURE "PQI DREG"
|
||||||
|
|
@ -67,7 +63,7 @@ struct pqi_device_registers {
|
||||||
/*
|
/*
|
||||||
* controller registers
|
* controller registers
|
||||||
*
|
*
|
||||||
* These are defined by the Microchip implementation.
|
* These are defined by the Microsemi implementation.
|
||||||
*
|
*
|
||||||
* Some registers (those named sis_*) are only used when in
|
* Some registers (those named sis_*) are only used when in
|
||||||
* legacy SIS mode before we transition the controller into
|
* legacy SIS mode before we transition the controller into
|
||||||
|
|
@ -87,8 +83,7 @@ struct pqi_ctrl_registers {
|
||||||
__le32 sis_ctrl_to_host_doorbell_clear; /* A0h */
|
__le32 sis_ctrl_to_host_doorbell_clear; /* A0h */
|
||||||
u8 reserved4[0xb0 - (0xa0 + sizeof(__le32))];
|
u8 reserved4[0xb0 - (0xa0 + sizeof(__le32))];
|
||||||
__le32 sis_driver_scratch; /* B0h */
|
__le32 sis_driver_scratch; /* B0h */
|
||||||
__le32 sis_product_identifier; /* B4h */
|
u8 reserved5[0xbc - (0xb0 + sizeof(__le32))];
|
||||||
u8 reserved5[0xbc - (0xb4 + sizeof(__le32))];
|
|
||||||
__le32 sis_firmware_status; /* BCh */
|
__le32 sis_firmware_status; /* BCh */
|
||||||
u8 reserved6[0x1000 - (0xbc + sizeof(__le32))];
|
u8 reserved6[0x1000 - (0xbc + sizeof(__le32))];
|
||||||
__le32 sis_mailbox[8]; /* 1000h */
|
__le32 sis_mailbox[8]; /* 1000h */
|
||||||
|
|
@ -102,12 +97,6 @@ struct pqi_ctrl_registers {
|
||||||
struct pqi_device_registers pqi_registers; /* 4000h */
|
struct pqi_device_registers pqi_registers; /* 4000h */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ((HZ) < 1000)
|
|
||||||
#define PQI_HZ 1000
|
|
||||||
#else
|
|
||||||
#define PQI_HZ (HZ)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PQI_DEVICE_REGISTERS_OFFSET 0x4000
|
#define PQI_DEVICE_REGISTERS_OFFSET 0x4000
|
||||||
|
|
||||||
enum pqi_io_path {
|
enum pqi_io_path {
|
||||||
|
|
@ -137,13 +126,10 @@ struct pqi_iu_header {
|
||||||
__le16 iu_length; /* in bytes - does not include the length */
|
__le16 iu_length; /* in bytes - does not include the length */
|
||||||
/* of this header */
|
/* of this header */
|
||||||
__le16 response_queue_id; /* specifies the OQ where the */
|
__le16 response_queue_id; /* specifies the OQ where the */
|
||||||
/* response IU is to be delivered */
|
/* response IU is to be delivered */
|
||||||
u16 driver_flags; /* reserved for driver use */
|
u8 work_area[2]; /* reserved for driver use */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* manifest constants for pqi_iu_header.driver_flags */
|
|
||||||
#define PQI_DRIVER_NONBLOCKABLE_REQUEST 0x1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to the PQI spec, the IU header is only the first 4 bytes of our
|
* According to the PQI spec, the IU header is only the first 4 bytes of our
|
||||||
* pqi_iu_header structure.
|
* pqi_iu_header structure.
|
||||||
|
|
@ -268,7 +254,6 @@ struct pqi_device_capability {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PQI_MAX_EMBEDDED_SG_DESCRIPTORS 4
|
#define PQI_MAX_EMBEDDED_SG_DESCRIPTORS 4
|
||||||
#define PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS 3
|
|
||||||
|
|
||||||
struct pqi_raid_path_request {
|
struct pqi_raid_path_request {
|
||||||
struct pqi_iu_header header;
|
struct pqi_iu_header header;
|
||||||
|
|
@ -289,10 +274,9 @@ struct pqi_raid_path_request {
|
||||||
u8 reserved4 : 2;
|
u8 reserved4 : 2;
|
||||||
u8 additional_cdb_bytes_usage : 3;
|
u8 additional_cdb_bytes_usage : 3;
|
||||||
u8 reserved5 : 3;
|
u8 reserved5 : 3;
|
||||||
u8 cdb[16];
|
u8 cdb[32];
|
||||||
u8 reserved6[12];
|
struct pqi_sg_descriptor
|
||||||
__le32 timeout;
|
sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
|
||||||
struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_aio_path_request {
|
struct pqi_aio_path_request {
|
||||||
|
|
@ -319,73 +303,8 @@ struct pqi_aio_path_request {
|
||||||
u8 cdb_length;
|
u8 cdb_length;
|
||||||
u8 lun_number[8];
|
u8 lun_number[8];
|
||||||
u8 reserved4[4];
|
u8 reserved4[4];
|
||||||
struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
|
struct pqi_sg_descriptor
|
||||||
};
|
sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
|
||||||
|
|
||||||
#define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */
|
|
||||||
|
|
||||||
struct pqi_aio_r1_path_request {
|
|
||||||
struct pqi_iu_header header;
|
|
||||||
__le16 request_id;
|
|
||||||
__le16 volume_id; /* ID of the RAID volume */
|
|
||||||
__le32 it_nexus_1; /* IT nexus of the 1st drive in the RAID volume */
|
|
||||||
__le32 it_nexus_2; /* IT nexus of the 2nd drive in the RAID volume */
|
|
||||||
__le32 it_nexus_3; /* IT nexus of the 3rd drive in the RAID volume */
|
|
||||||
__le32 data_length; /* total bytes to read/write */
|
|
||||||
u8 data_direction : 2;
|
|
||||||
u8 partial : 1;
|
|
||||||
u8 memory_type : 1;
|
|
||||||
u8 fence : 1;
|
|
||||||
u8 encryption_enable : 1;
|
|
||||||
u8 reserved : 2;
|
|
||||||
u8 task_attribute : 3;
|
|
||||||
u8 command_priority : 4;
|
|
||||||
u8 reserved2 : 1;
|
|
||||||
__le16 data_encryption_key_index;
|
|
||||||
u8 cdb[16];
|
|
||||||
__le16 error_index;
|
|
||||||
u8 num_sg_descriptors;
|
|
||||||
u8 cdb_length;
|
|
||||||
u8 num_drives; /* number of drives in the RAID volume (2 or 3) */
|
|
||||||
u8 reserved3[3];
|
|
||||||
__le32 encrypt_tweak_lower;
|
|
||||||
__le32 encrypt_tweak_upper;
|
|
||||||
struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PQI_DEFAULT_MAX_WRITE_RAID_5_6 (8 * 1024U)
|
|
||||||
#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_SAS_SATA (~0U)
|
|
||||||
#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME (32 * 1024U)
|
|
||||||
|
|
||||||
struct pqi_aio_r56_path_request {
|
|
||||||
struct pqi_iu_header header;
|
|
||||||
__le16 request_id;
|
|
||||||
__le16 volume_id; /* ID of the RAID volume */
|
|
||||||
__le32 data_it_nexus; /* IT nexus for the data drive */
|
|
||||||
__le32 p_parity_it_nexus; /* IT nexus for the P parity drive */
|
|
||||||
__le32 q_parity_it_nexus; /* IT nexus for the Q parity drive */
|
|
||||||
__le32 data_length; /* total bytes to read/write */
|
|
||||||
u8 data_direction : 2;
|
|
||||||
u8 partial : 1;
|
|
||||||
u8 mem_type : 1; /* 0 = PCIe, 1 = DDR */
|
|
||||||
u8 fence : 1;
|
|
||||||
u8 encryption_enable : 1;
|
|
||||||
u8 reserved : 2;
|
|
||||||
u8 task_attribute : 3;
|
|
||||||
u8 command_priority : 4;
|
|
||||||
u8 reserved1 : 1;
|
|
||||||
__le16 data_encryption_key_index;
|
|
||||||
u8 cdb[16];
|
|
||||||
__le16 error_index;
|
|
||||||
u8 num_sg_descriptors;
|
|
||||||
u8 cdb_length;
|
|
||||||
u8 xor_multiplier;
|
|
||||||
u8 reserved2[3];
|
|
||||||
__le32 encrypt_tweak_lower;
|
|
||||||
__le32 encrypt_tweak_upper;
|
|
||||||
__le64 row; /* row = logical LBA/blocks per row */
|
|
||||||
u8 reserved3[8];
|
|
||||||
struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_io_response {
|
struct pqi_io_response {
|
||||||
|
|
@ -428,28 +347,14 @@ struct pqi_event_config {
|
||||||
|
|
||||||
#define PQI_MAX_EVENT_DESCRIPTORS 255
|
#define PQI_MAX_EVENT_DESCRIPTORS 255
|
||||||
|
|
||||||
#define PQI_EVENT_OFA_MEMORY_ALLOCATION 0x0
|
|
||||||
#define PQI_EVENT_OFA_QUIESCE 0x1
|
|
||||||
#define PQI_EVENT_OFA_CANCELED 0x2
|
|
||||||
|
|
||||||
struct pqi_event_response {
|
struct pqi_event_response {
|
||||||
struct pqi_iu_header header;
|
struct pqi_iu_header header;
|
||||||
u8 event_type;
|
u8 event_type;
|
||||||
u8 reserved2 : 7;
|
u8 reserved2 : 7;
|
||||||
u8 request_acknowledge : 1;
|
u8 request_acknowlege : 1;
|
||||||
__le16 event_id;
|
__le16 event_id;
|
||||||
__le32 additional_event_id;
|
__le32 additional_event_id;
|
||||||
union {
|
u8 data[16];
|
||||||
struct {
|
|
||||||
__le32 bytes_requested;
|
|
||||||
u8 reserved[12];
|
|
||||||
} ofa_memory_allocation;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
__le16 reason; /* reason for cancellation */
|
|
||||||
u8 reserved[14];
|
|
||||||
} ofa_cancelled;
|
|
||||||
} data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_event_acknowledge_request {
|
struct pqi_event_acknowledge_request {
|
||||||
|
|
@ -464,8 +369,7 @@ struct pqi_task_management_request {
|
||||||
struct pqi_iu_header header;
|
struct pqi_iu_header header;
|
||||||
__le16 request_id;
|
__le16 request_id;
|
||||||
__le16 nexus_id;
|
__le16 nexus_id;
|
||||||
u8 reserved[2];
|
u8 reserved[4];
|
||||||
__le16 timeout;
|
|
||||||
u8 lun_number[8];
|
u8 lun_number[8];
|
||||||
__le16 protocol_specific;
|
__le16 protocol_specific;
|
||||||
__le16 outbound_queue_id_to_manage;
|
__le16 outbound_queue_id_to_manage;
|
||||||
|
|
@ -485,50 +389,6 @@ struct pqi_task_management_response {
|
||||||
u8 response_code;
|
u8 response_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_vendor_general_request {
|
|
||||||
struct pqi_iu_header header;
|
|
||||||
__le16 request_id;
|
|
||||||
__le16 function_code;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
__le16 first_section;
|
|
||||||
__le16 last_section;
|
|
||||||
u8 reserved[48];
|
|
||||||
} config_table_update;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
__le64 buffer_address;
|
|
||||||
__le32 buffer_length;
|
|
||||||
u8 reserved[40];
|
|
||||||
} ofa_memory_allocation;
|
|
||||||
} data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pqi_vendor_general_response {
|
|
||||||
struct pqi_iu_header header;
|
|
||||||
__le16 request_id;
|
|
||||||
__le16 function_code;
|
|
||||||
__le16 status;
|
|
||||||
u8 reserved[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PQI_VENDOR_GENERAL_CONFIG_TABLE_UPDATE 0
|
|
||||||
#define PQI_VENDOR_GENERAL_HOST_MEMORY_UPDATE 1
|
|
||||||
|
|
||||||
#define PQI_OFA_VERSION 1
|
|
||||||
#define PQI_OFA_SIGNATURE "OFA_QRM"
|
|
||||||
#define PQI_OFA_MAX_SG_DESCRIPTORS 64
|
|
||||||
|
|
||||||
struct pqi_ofa_memory {
|
|
||||||
__le64 signature; /* "OFA_QRM" */
|
|
||||||
__le16 version; /* version of this struct (1 = 1st version) */
|
|
||||||
u8 reserved[62];
|
|
||||||
__le32 bytes_allocated; /* total allocated memory in bytes */
|
|
||||||
__le16 num_memory_descriptors;
|
|
||||||
u8 reserved1[2];
|
|
||||||
struct pqi_sg_descriptor sg_descriptor[PQI_OFA_MAX_SG_DESCRIPTORS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pqi_aio_error_info {
|
struct pqi_aio_error_info {
|
||||||
u8 status;
|
u8 status;
|
||||||
u8 service_response;
|
u8 service_response;
|
||||||
|
|
@ -556,13 +416,9 @@ struct pqi_raid_error_info {
|
||||||
#define PQI_REQUEST_IU_TASK_MANAGEMENT 0x13
|
#define PQI_REQUEST_IU_TASK_MANAGEMENT 0x13
|
||||||
#define PQI_REQUEST_IU_RAID_PATH_IO 0x14
|
#define PQI_REQUEST_IU_RAID_PATH_IO 0x14
|
||||||
#define PQI_REQUEST_IU_AIO_PATH_IO 0x15
|
#define PQI_REQUEST_IU_AIO_PATH_IO 0x15
|
||||||
#define PQI_REQUEST_IU_AIO_PATH_RAID5_IO 0x18
|
|
||||||
#define PQI_REQUEST_IU_AIO_PATH_RAID6_IO 0x19
|
|
||||||
#define PQI_REQUEST_IU_AIO_PATH_RAID1_IO 0x1A
|
|
||||||
#define PQI_REQUEST_IU_GENERAL_ADMIN 0x60
|
#define PQI_REQUEST_IU_GENERAL_ADMIN 0x60
|
||||||
#define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72
|
#define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72
|
||||||
#define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73
|
#define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73
|
||||||
#define PQI_REQUEST_IU_VENDOR_GENERAL 0x75
|
|
||||||
#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6
|
#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6
|
||||||
|
|
||||||
#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81
|
#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81
|
||||||
|
|
@ -574,7 +430,6 @@ struct pqi_raid_error_info {
|
||||||
#define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3
|
#define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3
|
||||||
#define PQI_RESPONSE_IU_AIO_PATH_DISABLED 0xf4
|
#define PQI_RESPONSE_IU_AIO_PATH_DISABLED 0xf4
|
||||||
#define PQI_RESPONSE_IU_VENDOR_EVENT 0xf5
|
#define PQI_RESPONSE_IU_VENDOR_EVENT 0xf5
|
||||||
#define PQI_RESPONSE_IU_VENDOR_GENERAL 0xf7
|
|
||||||
|
|
||||||
#define PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY 0x0
|
#define PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY 0x0
|
||||||
#define PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ 0x10
|
#define PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ 0x10
|
||||||
|
|
@ -628,8 +483,6 @@ struct pqi_raid_error_info {
|
||||||
#define CISS_CMD_STATUS_TMF 0xd
|
#define CISS_CMD_STATUS_TMF 0xd
|
||||||
#define CISS_CMD_STATUS_AIO_DISABLED 0xe
|
#define CISS_CMD_STATUS_AIO_DISABLED 0xe
|
||||||
|
|
||||||
#define PQI_CMD_STATUS_ABORTED CISS_CMD_STATUS_ABORTED
|
|
||||||
|
|
||||||
#define PQI_NUM_EVENT_QUEUE_ELEMENTS 32
|
#define PQI_NUM_EVENT_QUEUE_ELEMENTS 32
|
||||||
#define PQI_EVENT_OQ_ELEMENT_LENGTH sizeof(struct pqi_event_response)
|
#define PQI_EVENT_OQ_ELEMENT_LENGTH sizeof(struct pqi_event_response)
|
||||||
|
|
||||||
|
|
@ -637,7 +490,6 @@ struct pqi_raid_error_info {
|
||||||
#define PQI_EVENT_TYPE_HARDWARE 0x2
|
#define PQI_EVENT_TYPE_HARDWARE 0x2
|
||||||
#define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4
|
#define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4
|
||||||
#define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5
|
#define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5
|
||||||
#define PQI_EVENT_TYPE_OFA 0xfb
|
|
||||||
#define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd
|
#define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd
|
||||||
#define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe
|
#define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe
|
||||||
|
|
||||||
|
|
@ -661,7 +513,6 @@ struct pqi_raid_error_info {
|
||||||
/* these values are defined by the PQI spec */
|
/* these values are defined by the PQI spec */
|
||||||
#define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE 255
|
#define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE 255
|
||||||
#define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE 65535
|
#define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE 65535
|
||||||
|
|
||||||
#define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT 64
|
#define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT 64
|
||||||
#define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT 16
|
#define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT 16
|
||||||
#define PQI_ADMIN_INDEX_ALIGNMENT 64
|
#define PQI_ADMIN_INDEX_ALIGNMENT 64
|
||||||
|
|
@ -703,7 +554,6 @@ typedef u32 pqi_index_t;
|
||||||
#define SOP_TASK_ATTRIBUTE_ACA 4
|
#define SOP_TASK_ATTRIBUTE_ACA 4
|
||||||
|
|
||||||
#define SOP_TMF_COMPLETE 0x0
|
#define SOP_TMF_COMPLETE 0x0
|
||||||
#define SOP_TMF_REJECTED 0x4
|
|
||||||
#define SOP_TMF_FUNCTION_SUCCEEDED 0x8
|
#define SOP_TMF_FUNCTION_SUCCEEDED 0x8
|
||||||
|
|
||||||
/* additional CDB bytes usage field codes */
|
/* additional CDB bytes usage field codes */
|
||||||
|
|
@ -731,8 +581,8 @@ struct pqi_admin_queues_aligned {
|
||||||
struct pqi_admin_queues {
|
struct pqi_admin_queues {
|
||||||
void *iq_element_array;
|
void *iq_element_array;
|
||||||
void *oq_element_array;
|
void *oq_element_array;
|
||||||
pqi_index_t __iomem *iq_ci;
|
volatile pqi_index_t *iq_ci;
|
||||||
pqi_index_t __iomem *oq_pi;
|
volatile pqi_index_t *oq_pi;
|
||||||
dma_addr_t iq_element_array_bus_addr;
|
dma_addr_t iq_element_array_bus_addr;
|
||||||
dma_addr_t oq_element_array_bus_addr;
|
dma_addr_t oq_element_array_bus_addr;
|
||||||
dma_addr_t iq_ci_bus_addr;
|
dma_addr_t iq_ci_bus_addr;
|
||||||
|
|
@ -756,8 +606,8 @@ struct pqi_queue_group {
|
||||||
dma_addr_t oq_element_array_bus_addr;
|
dma_addr_t oq_element_array_bus_addr;
|
||||||
__le32 __iomem *iq_pi[2];
|
__le32 __iomem *iq_pi[2];
|
||||||
pqi_index_t iq_pi_copy[2];
|
pqi_index_t iq_pi_copy[2];
|
||||||
pqi_index_t __iomem *iq_ci[2];
|
volatile pqi_index_t *iq_ci[2];
|
||||||
pqi_index_t __iomem *oq_pi;
|
volatile pqi_index_t *oq_pi;
|
||||||
dma_addr_t iq_ci_bus_addr[2];
|
dma_addr_t iq_ci_bus_addr[2];
|
||||||
dma_addr_t oq_pi_bus_addr;
|
dma_addr_t oq_pi_bus_addr;
|
||||||
__le32 __iomem *oq_ci;
|
__le32 __iomem *oq_ci;
|
||||||
|
|
@ -770,7 +620,7 @@ struct pqi_event_queue {
|
||||||
u16 oq_id;
|
u16 oq_id;
|
||||||
u16 int_msg_num;
|
u16 int_msg_num;
|
||||||
void *oq_element_array;
|
void *oq_element_array;
|
||||||
pqi_index_t __iomem *oq_pi;
|
volatile pqi_index_t *oq_pi;
|
||||||
dma_addr_t oq_element_array_bus_addr;
|
dma_addr_t oq_element_array_bus_addr;
|
||||||
dma_addr_t oq_pi_bus_addr;
|
dma_addr_t oq_pi_bus_addr;
|
||||||
__le32 __iomem *oq_ci;
|
__le32 __iomem *oq_ci;
|
||||||
|
|
@ -778,11 +628,7 @@ struct pqi_event_queue {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PQI_DEFAULT_QUEUE_GROUP 0
|
#define PQI_DEFAULT_QUEUE_GROUP 0
|
||||||
#if TORTUGA
|
|
||||||
#define PQI_MAX_QUEUE_GROUPS 1
|
|
||||||
#else
|
|
||||||
#define PQI_MAX_QUEUE_GROUPS PQI_MAX_MSIX_VECTORS
|
#define PQI_MAX_QUEUE_GROUPS PQI_MAX_MSIX_VECTORS
|
||||||
#endif
|
|
||||||
|
|
||||||
struct pqi_encryption_info {
|
struct pqi_encryption_info {
|
||||||
u16 data_encryption_key_index;
|
u16 data_encryption_key_index;
|
||||||
|
|
@ -796,13 +642,11 @@ struct pqi_encryption_info {
|
||||||
#define PQI_CONFIG_TABLE_MAX_LENGTH ((u16)~0)
|
#define PQI_CONFIG_TABLE_MAX_LENGTH ((u16)~0)
|
||||||
|
|
||||||
/* configuration table section IDs */
|
/* configuration table section IDs */
|
||||||
#define PQI_CONFIG_TABLE_ALL_SECTIONS (-1)
|
|
||||||
#define PQI_CONFIG_TABLE_SECTION_GENERAL_INFO 0
|
#define PQI_CONFIG_TABLE_SECTION_GENERAL_INFO 0
|
||||||
#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES 1
|
#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES 1
|
||||||
#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA 2
|
#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA 2
|
||||||
#define PQI_CONFIG_TABLE_SECTION_DEBUG 3
|
#define PQI_CONFIG_TABLE_SECTION_DEBUG 3
|
||||||
#define PQI_CONFIG_TABLE_SECTION_HEARTBEAT 4
|
#define PQI_CONFIG_TABLE_SECTION_HEARTBEAT 4
|
||||||
#define PQI_CONFIG_TABLE_SECTION_SOFT_RESET 5
|
|
||||||
|
|
||||||
struct pqi_config_table {
|
struct pqi_config_table {
|
||||||
u8 signature[8]; /* "CFGTABLE" */
|
u8 signature[8]; /* "CFGTABLE" */
|
||||||
|
|
@ -834,36 +678,6 @@ struct pqi_config_table_general_info {
|
||||||
/* command */
|
/* command */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_config_table_firmware_features {
|
|
||||||
struct pqi_config_table_section_header header;
|
|
||||||
__le16 num_elements;
|
|
||||||
u8 features_supported[];
|
|
||||||
/* u8 features_requested_by_host[]; */
|
|
||||||
/* u8 features_enabled[]; */
|
|
||||||
/* The 2 fields below are only valid if the MAX_KNOWN_FEATURE bit is set. */
|
|
||||||
/* __le16 firmware_max_known_feature; */
|
|
||||||
/* __le16 host_max_known_feature; */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PQI_FIRMWARE_FEATURE_OFA 0
|
|
||||||
#define PQI_FIRMWARE_FEATURE_SMP 1
|
|
||||||
#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10
|
|
||||||
#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11
|
|
||||||
#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13
|
|
||||||
#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14
|
|
||||||
#define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15
|
|
||||||
#define PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN 16
|
|
||||||
#define PQI_FIRMWARE_FEATURE_MAXIMUM 16
|
|
||||||
|
|
||||||
struct pqi_config_table_debug {
|
struct pqi_config_table_debug {
|
||||||
struct pqi_config_table_section_header header;
|
struct pqi_config_table_section_header header;
|
||||||
__le32 scratchpad;
|
__le32 scratchpad;
|
||||||
|
|
@ -874,22 +688,6 @@ struct pqi_config_table_heartbeat {
|
||||||
__le32 heartbeat_counter;
|
__le32 heartbeat_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pqi_config_table_soft_reset {
|
|
||||||
struct pqi_config_table_section_header header;
|
|
||||||
u8 soft_reset_status;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PQI_SOFT_RESET_INITIATE 0x1
|
|
||||||
#define PQI_SOFT_RESET_ABORT 0x2
|
|
||||||
|
|
||||||
enum pqi_soft_reset_status {
|
|
||||||
RESET_INITIATE_FIRMWARE,
|
|
||||||
RESET_INITIATE_DRIVER,
|
|
||||||
RESET_ABORT,
|
|
||||||
RESET_NORESPONSE,
|
|
||||||
RESET_TIMEDOUT
|
|
||||||
};
|
|
||||||
|
|
||||||
union pqi_reset_register {
|
union pqi_reset_register {
|
||||||
struct {
|
struct {
|
||||||
u32 reset_type : 3;
|
u32 reset_type : 3;
|
||||||
|
|
@ -912,17 +710,10 @@ union pqi_reset_register {
|
||||||
|
|
||||||
#define PQI_RESET_POLL_INTERVAL_MSECS 100
|
#define PQI_RESET_POLL_INTERVAL_MSECS 100
|
||||||
|
|
||||||
#if TORTUGA
|
|
||||||
#define PQI_MAX_OUTSTANDING_REQUESTS 32
|
|
||||||
#define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP PQI_MAX_OUTSTANDING_REQUESTS
|
|
||||||
#define PQI_MAX_TRANSFER_SIZE (512 * 1024U)
|
|
||||||
#define PQI_MAX_TRANSFER_SIZE_KDUMP PQI_MAX_TRANSFER_SIZE
|
|
||||||
#else
|
|
||||||
#define PQI_MAX_OUTSTANDING_REQUESTS ((u32)~0)
|
#define PQI_MAX_OUTSTANDING_REQUESTS ((u32)~0)
|
||||||
#define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP 32
|
#define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP 32
|
||||||
#define PQI_MAX_TRANSFER_SIZE (4 * 1024U * 1024U)
|
#define PQI_MAX_TRANSFER_SIZE (1024U * 1024U)
|
||||||
#define PQI_MAX_TRANSFER_SIZE_KDUMP (512 * 1024U)
|
#define PQI_MAX_TRANSFER_SIZE_KDUMP (512 * 1024U)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RAID_MAP_MAX_ENTRIES 1024
|
#define RAID_MAP_MAX_ENTRIES 1024
|
||||||
|
|
||||||
|
|
@ -931,21 +722,13 @@ union pqi_reset_register {
|
||||||
#define PQI_HBA_BUS 2
|
#define PQI_HBA_BUS 2
|
||||||
#define PQI_EXTERNAL_RAID_VOLUME_BUS 3
|
#define PQI_EXTERNAL_RAID_VOLUME_BUS 3
|
||||||
#define PQI_MAX_BUS PQI_EXTERNAL_RAID_VOLUME_BUS
|
#define PQI_MAX_BUS PQI_EXTERNAL_RAID_VOLUME_BUS
|
||||||
#define PQI_VSEP_CISS_BTL 379
|
|
||||||
|
|
||||||
struct report_lun_header {
|
struct report_lun_header {
|
||||||
__be32 list_length;
|
__be32 list_length;
|
||||||
u8 flags;
|
u8 extended_response;
|
||||||
u8 reserved[3];
|
u8 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for flags field of struct report_lun_header */
|
|
||||||
#define CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID (1 << 0)
|
|
||||||
#define CISS_REPORT_LOG_FLAG_QUEUE_DEPTH (1 << 5)
|
|
||||||
#define CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX (1 << 6)
|
|
||||||
|
|
||||||
#define CISS_REPORT_PHYS_FLAG_OTHER (1 << 1)
|
|
||||||
|
|
||||||
struct report_log_lun_extended_entry {
|
struct report_log_lun_extended_entry {
|
||||||
u8 lunid[8];
|
u8 lunid[8];
|
||||||
u8 volume_id[16];
|
u8 volume_id[16];
|
||||||
|
|
@ -967,7 +750,7 @@ struct report_phys_lun_extended_entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for device_flags field of struct report_phys_lun_extended_entry */
|
/* for device_flags field of struct report_phys_lun_extended_entry */
|
||||||
#define CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED 0x8
|
#define REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED 0x8
|
||||||
|
|
||||||
struct report_phys_lun_extended {
|
struct report_phys_lun_extended {
|
||||||
struct report_lun_header header;
|
struct report_lun_header header;
|
||||||
|
|
@ -980,7 +763,7 @@ struct raid_map_disk_data {
|
||||||
u8 reserved[2];
|
u8 reserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for flags field of RAID map */
|
/* constants for flags field of RAID map */
|
||||||
#define RAID_MAP_ENCRYPTION_ENABLED 0x1
|
#define RAID_MAP_ENCRYPTION_ENABLED 0x1
|
||||||
|
|
||||||
struct raid_map {
|
struct raid_map {
|
||||||
|
|
@ -1010,65 +793,8 @@ struct raid_map {
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
struct pqi_scsi_dev_raid_map_data {
|
|
||||||
bool is_write;
|
|
||||||
u8 raid_level;
|
|
||||||
u32 map_index;
|
|
||||||
u64 first_block;
|
|
||||||
u64 last_block;
|
|
||||||
u32 data_length;
|
|
||||||
u32 block_cnt;
|
|
||||||
u32 blocks_per_row;
|
|
||||||
u64 first_row;
|
|
||||||
u64 last_row;
|
|
||||||
u32 first_row_offset;
|
|
||||||
u32 last_row_offset;
|
|
||||||
u32 first_column;
|
|
||||||
u32 last_column;
|
|
||||||
u64 r5or6_first_row;
|
|
||||||
u64 r5or6_last_row;
|
|
||||||
u32 r5or6_first_row_offset;
|
|
||||||
u32 r5or6_last_row_offset;
|
|
||||||
u32 r5or6_first_column;
|
|
||||||
u32 r5or6_last_column;
|
|
||||||
u16 data_disks_per_row;
|
|
||||||
u32 total_disks_per_row;
|
|
||||||
u16 layout_map_count;
|
|
||||||
u32 stripesize;
|
|
||||||
u16 strip_size;
|
|
||||||
u32 first_group;
|
|
||||||
u32 last_group;
|
|
||||||
u32 map_row;
|
|
||||||
u32 aio_handle;
|
|
||||||
u64 disk_block;
|
|
||||||
u32 disk_block_cnt;
|
|
||||||
u8 cdb[16];
|
|
||||||
u8 cdb_length;
|
|
||||||
|
|
||||||
/* RAID 1 specific */
|
|
||||||
#define NUM_RAID1_MAP_ENTRIES 3
|
|
||||||
u32 num_it_nexus_entries;
|
|
||||||
u32 it_nexus[NUM_RAID1_MAP_ENTRIES];
|
|
||||||
|
|
||||||
/* RAID 5 / RAID 6 specific */
|
|
||||||
u32 p_parity_it_nexus; /* aio_handle */
|
|
||||||
u32 q_parity_it_nexus; /* aio_handle */
|
|
||||||
u8 xor_mult;
|
|
||||||
u64 row;
|
|
||||||
u64 stripe_lba;
|
|
||||||
u32 p_index;
|
|
||||||
u32 q_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
|
#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
|
||||||
|
|
||||||
#define NUM_STREAMS_PER_LUN 8
|
|
||||||
|
|
||||||
struct pqi_stream_data {
|
|
||||||
u64 next_lba;
|
|
||||||
u32 last_accessed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pqi_scsi_dev {
|
struct pqi_scsi_dev {
|
||||||
int devtype; /* as reported by INQUIRY commmand */
|
int devtype; /* as reported by INQUIRY commmand */
|
||||||
u8 device_type; /* as reported by */
|
u8 device_type; /* as reported by */
|
||||||
|
|
@ -1082,15 +808,13 @@ struct pqi_scsi_dev {
|
||||||
u8 volume_id[16];
|
u8 volume_id[16];
|
||||||
u8 is_physical_device : 1;
|
u8 is_physical_device : 1;
|
||||||
u8 is_external_raid_device : 1;
|
u8 is_external_raid_device : 1;
|
||||||
u8 is_expander_smp_device : 1;
|
|
||||||
u8 target_lun_valid : 1;
|
u8 target_lun_valid : 1;
|
||||||
u8 device_gone : 1;
|
u8 device_gone : 1;
|
||||||
u8 new_device : 1;
|
u8 new_device : 1;
|
||||||
u8 keep_device : 1;
|
u8 keep_device : 1;
|
||||||
u8 volume_offline : 1;
|
u8 volume_offline : 1;
|
||||||
u8 rescan : 1;
|
|
||||||
bool aio_enabled; /* only valid for physical disks */
|
bool aio_enabled; /* only valid for physical disks */
|
||||||
bool in_remove;
|
bool in_reset;
|
||||||
bool device_offline;
|
bool device_offline;
|
||||||
u8 vendor[8]; /* bytes 8-15 of inquiry data */
|
u8 vendor[8]; /* bytes 8-15 of inquiry data */
|
||||||
u8 model[16]; /* bytes 16-31 of inquiry data */
|
u8 model[16]; /* bytes 16-31 of inquiry data */
|
||||||
|
|
@ -1103,17 +827,13 @@ struct pqi_scsi_dev {
|
||||||
u8 active_path_index;
|
u8 active_path_index;
|
||||||
u8 path_map;
|
u8 path_map;
|
||||||
u8 bay;
|
u8 bay;
|
||||||
u8 box_index;
|
|
||||||
u8 phys_box_on_bus;
|
|
||||||
u8 phy_connected_dev_type;
|
|
||||||
u8 box[8];
|
u8 box[8];
|
||||||
u16 phys_connector[8];
|
u16 phys_connector[8];
|
||||||
u8 phy_id;
|
|
||||||
bool raid_bypass_configured; /* RAID bypass configured */
|
bool raid_bypass_configured; /* RAID bypass configured */
|
||||||
bool raid_bypass_enabled; /* RAID bypass enabled */
|
bool raid_bypass_enabled; /* RAID bypass enabled */
|
||||||
u32 next_bypass_group;
|
int offload_to_mirror; /* Send next RAID bypass request */
|
||||||
|
/* to mirror drive. */
|
||||||
struct raid_map *raid_map; /* RAID bypass map */
|
struct raid_map *raid_map; /* RAID bypass map */
|
||||||
u32 max_transfer_encrypted;
|
|
||||||
|
|
||||||
struct pqi_sas_port *sas_port;
|
struct pqi_sas_port *sas_port;
|
||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
|
|
@ -1123,13 +843,12 @@ struct pqi_scsi_dev {
|
||||||
struct list_head add_list_entry;
|
struct list_head add_list_entry;
|
||||||
struct list_head delete_list_entry;
|
struct list_head delete_list_entry;
|
||||||
|
|
||||||
struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN];
|
|
||||||
atomic_t scsi_cmds_outstanding;
|
atomic_t scsi_cmds_outstanding;
|
||||||
atomic_t raid_bypass_cnt;
|
|
||||||
u8 page_83_identifier[16];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* VPD inquiry pages */
|
/* VPD inquiry pages */
|
||||||
|
#define SCSI_VPD_SUPPORTED_PAGES 0x0 /* standard page */
|
||||||
|
#define SCSI_VPD_DEVICE_ID 0x83 /* standard page */
|
||||||
#define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */
|
#define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */
|
||||||
#define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */
|
#define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */
|
||||||
#define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */
|
#define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */
|
||||||
|
|
@ -1195,7 +914,6 @@ struct pqi_sas_node {
|
||||||
struct pqi_sas_port {
|
struct pqi_sas_port {
|
||||||
struct list_head port_list_entry;
|
struct list_head port_list_entry;
|
||||||
u64 sas_address;
|
u64 sas_address;
|
||||||
struct pqi_scsi_dev *device;
|
|
||||||
struct sas_port *port;
|
struct sas_port *port;
|
||||||
int next_phy_index;
|
int next_phy_index;
|
||||||
struct list_head phy_list_head;
|
struct list_head phy_list_head;
|
||||||
|
|
@ -1227,13 +945,13 @@ struct pqi_io_request {
|
||||||
struct list_head request_list_entry;
|
struct list_head request_list_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PQI_NUM_SUPPORTED_EVENTS 7
|
#define PQI_NUM_SUPPORTED_EVENTS 6
|
||||||
|
|
||||||
struct pqi_event {
|
struct pqi_event {
|
||||||
bool pending;
|
bool pending;
|
||||||
u8 event_type;
|
u8 event_type;
|
||||||
u16 event_id;
|
__le16 event_id;
|
||||||
u32 additional_event_id;
|
__le32 additional_event_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PQI_RESERVED_IO_SLOTS_LUN_RESET 1
|
#define PQI_RESERVED_IO_SLOTS_LUN_RESET 1
|
||||||
|
|
@ -1243,20 +961,10 @@ struct pqi_event {
|
||||||
(PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \
|
(PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \
|
||||||
PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS)
|
PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS)
|
||||||
|
|
||||||
#define PQI_CTRL_PRODUCT_ID_GEN1 0
|
|
||||||
#define PQI_CTRL_PRODUCT_ID_GEN2 7
|
|
||||||
#define PQI_CTRL_PRODUCT_REVISION_A 0
|
|
||||||
#define PQI_CTRL_PRODUCT_REVISION_B 1
|
|
||||||
|
|
||||||
struct pqi_ctrl_info {
|
struct pqi_ctrl_info {
|
||||||
unsigned int ctrl_id;
|
unsigned int ctrl_id;
|
||||||
struct pci_dev *pci_dev;
|
struct pci_dev *pci_dev;
|
||||||
char firmware_version[32];
|
char firmware_version[11];
|
||||||
char serial_number[17];
|
|
||||||
char model[17];
|
|
||||||
char vendor[9];
|
|
||||||
u8 product_id;
|
|
||||||
u8 product_revision;
|
|
||||||
void __iomem *iomem_base;
|
void __iomem *iomem_base;
|
||||||
struct pqi_ctrl_registers __iomem *registers;
|
struct pqi_ctrl_registers __iomem *registers;
|
||||||
struct pqi_device_registers __iomem *pqi_registers;
|
struct pqi_device_registers __iomem *pqi_registers;
|
||||||
|
|
@ -1286,7 +994,6 @@ struct pqi_ctrl_info {
|
||||||
u16 max_inbound_iu_length_per_firmware;
|
u16 max_inbound_iu_length_per_firmware;
|
||||||
u16 max_inbound_iu_length;
|
u16 max_inbound_iu_length;
|
||||||
unsigned int max_sg_per_iu;
|
unsigned int max_sg_per_iu;
|
||||||
unsigned int max_sg_per_r56_iu;
|
|
||||||
void *admin_queue_memory_base;
|
void *admin_queue_memory_base;
|
||||||
u32 admin_queue_memory_length;
|
u32 admin_queue_memory_length;
|
||||||
dma_addr_t admin_queue_memory_base_dma_handle;
|
dma_addr_t admin_queue_memory_base_dma_handle;
|
||||||
|
|
@ -1300,8 +1007,6 @@ struct pqi_ctrl_info {
|
||||||
int max_msix_vectors;
|
int max_msix_vectors;
|
||||||
int num_msix_vectors_enabled;
|
int num_msix_vectors_enabled;
|
||||||
int num_msix_vectors_initialized;
|
int num_msix_vectors_initialized;
|
||||||
u32 msix_vectors[PQI_MAX_MSIX_VECTORS];
|
|
||||||
void *intr_data[PQI_MAX_MSIX_VECTORS];
|
|
||||||
int event_irq;
|
int event_irq;
|
||||||
struct Scsi_Host *scsi_host;
|
struct Scsi_Host *scsi_host;
|
||||||
|
|
||||||
|
|
@ -1309,27 +1014,10 @@ struct pqi_ctrl_info {
|
||||||
struct mutex lun_reset_mutex;
|
struct mutex lun_reset_mutex;
|
||||||
bool controller_online;
|
bool controller_online;
|
||||||
bool block_requests;
|
bool block_requests;
|
||||||
bool scan_blocked;
|
|
||||||
u8 inbound_spanning_supported : 1;
|
u8 inbound_spanning_supported : 1;
|
||||||
u8 outbound_spanning_supported : 1;
|
u8 outbound_spanning_supported : 1;
|
||||||
u8 pqi_mode_enabled : 1;
|
u8 pqi_mode_enabled : 1;
|
||||||
u8 pqi_reset_quiesce_supported : 1;
|
u8 pqi_reset_quiesce_supported : 1;
|
||||||
u8 soft_reset_handshake_supported : 1;
|
|
||||||
u8 raid_iu_timeout_supported : 1;
|
|
||||||
u8 tmf_iu_timeout_supported : 1;
|
|
||||||
u8 unique_wwid_in_report_phys_lun_supported : 1;
|
|
||||||
u8 enable_r1_writes : 1;
|
|
||||||
u8 enable_r5_writes : 1;
|
|
||||||
u8 enable_r6_writes : 1;
|
|
||||||
u8 lv_drive_type_mix_valid : 1;
|
|
||||||
u8 enable_stream_detection : 1;
|
|
||||||
|
|
||||||
u8 ciss_report_log_flags;
|
|
||||||
u32 max_transfer_encrypted_sas_sata;
|
|
||||||
u32 max_transfer_encrypted_nvme;
|
|
||||||
u32 max_write_raid_5_6;
|
|
||||||
u32 max_write_raid_1_10_2drive;
|
|
||||||
u32 max_write_raid_1_10_3drive;
|
|
||||||
|
|
||||||
struct list_head scsi_device_list;
|
struct list_head scsi_device_list;
|
||||||
spinlock_t scsi_device_list_lock;
|
spinlock_t scsi_device_list_lock;
|
||||||
|
|
@ -1350,7 +1038,6 @@ struct pqi_ctrl_info {
|
||||||
int previous_num_interrupts;
|
int previous_num_interrupts;
|
||||||
u32 previous_heartbeat_count;
|
u32 previous_heartbeat_count;
|
||||||
__le32 __iomem *heartbeat_counter;
|
__le32 __iomem *heartbeat_counter;
|
||||||
u8 __iomem *soft_reset_status;
|
|
||||||
struct timer_list heartbeat_timer;
|
struct timer_list heartbeat_timer;
|
||||||
struct work_struct ctrl_offline_work;
|
struct work_struct ctrl_offline_work;
|
||||||
|
|
||||||
|
|
@ -1359,16 +1046,9 @@ struct pqi_ctrl_info {
|
||||||
atomic_t num_blocked_threads;
|
atomic_t num_blocked_threads;
|
||||||
wait_queue_head_t block_requests_wait;
|
wait_queue_head_t block_requests_wait;
|
||||||
|
|
||||||
struct mutex ofa_mutex;
|
struct list_head raid_bypass_retry_list;
|
||||||
struct pqi_ofa_memory *pqi_ofa_mem_virt_addr;
|
spinlock_t raid_bypass_retry_list_lock;
|
||||||
dma_addr_t pqi_ofa_mem_dma_handle;
|
struct work_struct raid_bypass_retry_work;
|
||||||
void **pqi_ofa_chunk_virt_addr;
|
|
||||||
struct work_struct ofa_memory_alloc_work;
|
|
||||||
struct work_struct ofa_quiesce_work;
|
|
||||||
u32 ofa_bytes_requested;
|
|
||||||
u16 ofa_cancel_reason;
|
|
||||||
|
|
||||||
atomic_t total_scmds_outstanding;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum pqi_ctrl_mode {
|
enum pqi_ctrl_mode {
|
||||||
|
|
@ -1387,21 +1067,19 @@ enum pqi_ctrl_mode {
|
||||||
#define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */
|
#define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */
|
||||||
#define CISS_GET_RAID_MAP 0xc8
|
#define CISS_GET_RAID_MAP 0xc8
|
||||||
|
|
||||||
|
/* constants for CISS_REPORT_LOG/CISS_REPORT_PHYS commands */
|
||||||
|
#define CISS_REPORT_LOG_EXTENDED 0x1
|
||||||
|
#define CISS_REPORT_PHYS_EXTENDED 0x2
|
||||||
|
|
||||||
/* BMIC commands */
|
/* BMIC commands */
|
||||||
#define BMIC_IDENTIFY_CONTROLLER 0x11
|
#define BMIC_IDENTIFY_CONTROLLER 0x11
|
||||||
#define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15
|
#define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15
|
||||||
#define BMIC_READ 0x26
|
#define BMIC_READ 0x26
|
||||||
#define BMIC_WRITE 0x27
|
#define BMIC_WRITE 0x27
|
||||||
#define BMIC_SENSE_FEATURE 0x61
|
|
||||||
#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
|
#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
|
||||||
#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
|
#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
|
||||||
#define BMIC_CSMI_PASSTHRU 0x68
|
|
||||||
#define BMIC_WRITE_HOST_WELLNESS 0xa5
|
#define BMIC_WRITE_HOST_WELLNESS 0xa5
|
||||||
#define BMIC_FLUSH_CACHE 0xc2
|
#define BMIC_FLUSH_CACHE 0xc2
|
||||||
#define BMIC_SET_DIAG_OPTIONS 0xf4
|
|
||||||
#define BMIC_SENSE_DIAG_OPTIONS 0xf5
|
|
||||||
|
|
||||||
#define CSMI_CC_SAS_SMP_PASSTHRU 0x17
|
|
||||||
|
|
||||||
#define SA_FLUSH_CACHE 0x1
|
#define SA_FLUSH_CACHE 0x1
|
||||||
|
|
||||||
|
|
@ -1412,19 +1090,6 @@ enum pqi_ctrl_mode {
|
||||||
(((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
|
(((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
|
||||||
CISS_GET_LEVEL_2_TARGET((lunid)))
|
CISS_GET_LEVEL_2_TARGET((lunid)))
|
||||||
|
|
||||||
#define LV_GET_DRIVE_TYPE_MIX(lunid) ((lunid)[6])
|
|
||||||
|
|
||||||
#define LV_DRIVE_TYPE_MIX_UNKNOWN 0
|
|
||||||
#define LV_DRIVE_TYPE_MIX_NO_RESTRICTION 1
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SAS_HDD_ONLY 2
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SATA_HDD_ONLY 3
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SAS_OR_SATA_SSD_ONLY 4
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SAS_SSD_ONLY 5
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SATA_SSD_ONLY 6
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SAS_ONLY 7
|
|
||||||
#define LV_DRIVE_TYPE_MIX_SATA_ONLY 8
|
|
||||||
#define LV_DRIVE_TYPE_MIX_NVME_ONLY 9
|
|
||||||
|
|
||||||
#define NO_TIMEOUT ((unsigned long) -1)
|
#define NO_TIMEOUT ((unsigned long) -1)
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
@ -1432,38 +1097,16 @@ enum pqi_ctrl_mode {
|
||||||
struct bmic_identify_controller {
|
struct bmic_identify_controller {
|
||||||
u8 configured_logical_drive_count;
|
u8 configured_logical_drive_count;
|
||||||
__le32 configuration_signature;
|
__le32 configuration_signature;
|
||||||
u8 firmware_version_short[4];
|
u8 firmware_version[4];
|
||||||
u8 reserved[145];
|
u8 reserved[145];
|
||||||
__le16 extended_logical_unit_count;
|
__le16 extended_logical_unit_count;
|
||||||
u8 reserved1[34];
|
u8 reserved1[34];
|
||||||
__le16 firmware_build_number;
|
__le16 firmware_build_number;
|
||||||
u8 reserved2[8];
|
u8 reserved2[100];
|
||||||
u8 vendor_id[8];
|
|
||||||
u8 product_id[16];
|
|
||||||
u8 reserved3[62];
|
|
||||||
__le32 extra_controller_flags;
|
|
||||||
u8 reserved4[2];
|
|
||||||
u8 controller_mode;
|
u8 controller_mode;
|
||||||
u8 spare_part_number[32];
|
u8 reserved3[32];
|
||||||
u8 firmware_version_long[32];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* constants for extra_controller_flags field of bmic_identify_controller */
|
|
||||||
#define BMIC_IDENTIFY_EXTRA_FLAGS_LONG_FW_VERSION_SUPPORTED 0x20000000
|
|
||||||
|
|
||||||
struct bmic_sense_subsystem_info {
|
|
||||||
u8 reserved[44];
|
|
||||||
u8 ctrl_serial_number[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* constants for device_type field */
|
|
||||||
#define SA_DEVICE_TYPE_SATA 0x1
|
|
||||||
#define SA_DEVICE_TYPE_SAS 0x2
|
|
||||||
#define SA_DEVICE_TYPE_EXPANDER_SMP 0x5
|
|
||||||
#define SA_DEVICE_TYPE_SES 0x6
|
|
||||||
#define SA_DEVICE_TYPE_CONTROLLER 0x7
|
|
||||||
#define SA_DEVICE_TYPE_NVME 0x9
|
|
||||||
|
|
||||||
struct bmic_identify_physical_device {
|
struct bmic_identify_physical_device {
|
||||||
u8 scsi_bus; /* SCSI Bus number on controller */
|
u8 scsi_bus; /* SCSI Bus number on controller */
|
||||||
u8 scsi_id; /* SCSI ID on this bus */
|
u8 scsi_id; /* SCSI ID on this bus */
|
||||||
|
|
@ -1488,7 +1131,7 @@ struct bmic_identify_physical_device {
|
||||||
__le32 rpm; /* drive rotational speed in RPM */
|
__le32 rpm; /* drive rotational speed in RPM */
|
||||||
u8 device_type; /* type of drive */
|
u8 device_type; /* type of drive */
|
||||||
u8 sata_version; /* only valid when device_type = */
|
u8 sata_version; /* only valid when device_type = */
|
||||||
/* SA_DEVICE_TYPE_SATA */
|
/* BMIC_DEVICE_TYPE_SATA */
|
||||||
__le64 big_total_block_count;
|
__le64 big_total_block_count;
|
||||||
__le64 ris_starting_lba;
|
__le64 ris_starting_lba;
|
||||||
__le32 ris_size;
|
__le32 ris_size;
|
||||||
|
|
@ -1544,78 +1187,6 @@ struct bmic_identify_physical_device {
|
||||||
u8 padding_to_multiple_of_512[9];
|
u8 padding_to_multiple_of_512[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BMIC_SENSE_FEATURE_IO_PAGE 0x8
|
|
||||||
#define BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE 0x2
|
|
||||||
|
|
||||||
struct bmic_sense_feature_buffer_header {
|
|
||||||
u8 page_code;
|
|
||||||
u8 subpage_code;
|
|
||||||
__le16 buffer_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_sense_feature_page_header {
|
|
||||||
u8 page_code;
|
|
||||||
u8 subpage_code;
|
|
||||||
__le16 page_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_sense_feature_io_page_aio_subpage {
|
|
||||||
struct bmic_sense_feature_page_header header;
|
|
||||||
u8 firmware_read_support;
|
|
||||||
u8 driver_read_support;
|
|
||||||
u8 firmware_write_support;
|
|
||||||
u8 driver_write_support;
|
|
||||||
__le16 max_transfer_encrypted_sas_sata;
|
|
||||||
__le16 max_transfer_encrypted_nvme;
|
|
||||||
__le16 max_write_raid_5_6;
|
|
||||||
__le16 max_write_raid_1_10_2drive;
|
|
||||||
__le16 max_write_raid_1_10_3drive;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_smp_request {
|
|
||||||
u8 frame_type;
|
|
||||||
u8 function;
|
|
||||||
u8 allocated_response_length;
|
|
||||||
u8 request_length;
|
|
||||||
u8 additional_request_bytes[1016];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_smp_response {
|
|
||||||
u8 frame_type;
|
|
||||||
u8 function;
|
|
||||||
u8 function_result;
|
|
||||||
u8 response_length;
|
|
||||||
u8 additional_response_bytes[1016];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_csmi_ioctl_header {
|
|
||||||
__le32 header_length;
|
|
||||||
u8 signature[8];
|
|
||||||
__le32 timeout;
|
|
||||||
__le32 control_code;
|
|
||||||
__le32 return_code;
|
|
||||||
__le32 length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_csmi_smp_passthru {
|
|
||||||
u8 phy_identifier;
|
|
||||||
u8 port_identifier;
|
|
||||||
u8 connection_rate;
|
|
||||||
u8 reserved;
|
|
||||||
__be64 destination_sas_address;
|
|
||||||
__le32 request_length;
|
|
||||||
struct bmic_smp_request request;
|
|
||||||
u8 connection_status;
|
|
||||||
u8 reserved1[3];
|
|
||||||
__le32 response_length;
|
|
||||||
struct bmic_smp_response response;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_csmi_smp_passthru_buffer {
|
|
||||||
struct bmic_csmi_ioctl_header ioctl_header;
|
|
||||||
struct bmic_csmi_smp_passthru parameters;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bmic_flush_cache {
|
struct bmic_flush_cache {
|
||||||
u8 disable_flag;
|
u8 disable_flag;
|
||||||
u8 system_power_action;
|
u8 system_power_action;
|
||||||
|
|
@ -1633,22 +1204,8 @@ enum bmic_flush_cache_shutdown_event {
|
||||||
RESTART = 4
|
RESTART = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bmic_diag_options {
|
|
||||||
__le32 options;
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost)
|
|
||||||
{
|
|
||||||
void *hostdata = shost_priv(shost);
|
|
||||||
|
|
||||||
return *((struct pqi_ctrl_info **)hostdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
|
|
||||||
struct sas_rphy *rphy);
|
|
||||||
int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd);
|
|
||||||
int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info);
|
int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info);
|
||||||
void pqi_delete_sas_host(struct pqi_ctrl_info *ctrl_info);
|
void pqi_delete_sas_host(struct pqi_ctrl_info *ctrl_info);
|
||||||
int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
|
int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
|
||||||
|
|
@ -1657,10 +1214,7 @@ void pqi_remove_sas_device(struct pqi_scsi_dev *device);
|
||||||
struct pqi_scsi_dev *pqi_find_device_by_sas_rphy(
|
struct pqi_scsi_dev *pqi_find_device_by_sas_rphy(
|
||||||
struct pqi_ctrl_info *ctrl_info, struct sas_rphy *rphy);
|
struct pqi_ctrl_info *ctrl_info, struct sas_rphy *rphy);
|
||||||
void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd);
|
void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd);
|
||||||
int pqi_csmi_smp_passthru(struct pqi_ctrl_info *ctrl_info,
|
|
||||||
struct bmic_csmi_smp_passthru_buffer *buffer, size_t buffer_length,
|
|
||||||
struct pqi_raid_error_info *error_info);
|
|
||||||
|
|
||||||
extern struct sas_function_template pqi_sas_transport_functions;
|
extern struct sas_function_template pqi_sas_transport_functions;
|
||||||
|
|
||||||
#endif /* _SMARTPQI_H */
|
#endif /* _SMARTPQI_H */
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,311 +0,0 @@
|
||||||
/*
|
|
||||||
* driver for Microchip PQI-based storage controllers
|
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/bsg-lib.h>
|
|
||||||
#include <scsi/scsi_cmnd.h>
|
|
||||||
#include <scsi/scsi_device.h>
|
|
||||||
#include "smartpqi.h"
|
|
||||||
#include "smartpqi_kernel_compat.h"
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_2011_03_QUEUECOMMAND
|
|
||||||
|
|
||||||
int pqi_scsi_queue_command_compat(struct scsi_cmnd *scmd,
|
|
||||||
void (*done)(struct scsi_cmnd *))
|
|
||||||
{
|
|
||||||
scmd->SCp.ptr = (char *)done;
|
|
||||||
|
|
||||||
return pqi_scsi_queue_command(scmd->device->host, scmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_2011_03_QUEUECOMMAND */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE
|
|
||||||
|
|
||||||
int pci_enable_msix_range(struct pci_dev *pci_dev, struct msix_entry *entries,
|
|
||||||
int minvec, int maxvec)
|
|
||||||
{
|
|
||||||
int nvec = maxvec;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (maxvec < minvec)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
do {
|
|
||||||
rc = pci_enable_msix(pci_dev, entries, nvec);
|
|
||||||
if (rc < 0)
|
|
||||||
return rc;
|
|
||||||
if (rc > 0) {
|
|
||||||
if (rc < minvec)
|
|
||||||
return -ENOSPC;
|
|
||||||
nvec = rc;
|
|
||||||
}
|
|
||||||
} while (rc);
|
|
||||||
|
|
||||||
return nvec;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH
|
|
||||||
|
|
||||||
int scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
|
|
||||||
{
|
|
||||||
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), queue_depth);
|
|
||||||
|
|
||||||
return queue_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pqi_change_queue_depth(struct scsi_device *sdev, int qdepth,
|
|
||||||
int reason)
|
|
||||||
{
|
|
||||||
if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) {
|
|
||||||
struct pqi_scsi_dev *device = sdev->hostdata;
|
|
||||||
|
|
||||||
if (!device)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
if (qdepth < 1)
|
|
||||||
qdepth = 1;
|
|
||||||
else if (qdepth > device->queue_depth)
|
|
||||||
qdepth = device->queue_depth;
|
|
||||||
|
|
||||||
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
|
|
||||||
|
|
||||||
} else if (reason == SCSI_QDEPTH_QFULL)
|
|
||||||
scsi_track_queue_full(sdev, qdepth);
|
|
||||||
else
|
|
||||||
return -ENOTSUPP;
|
|
||||||
|
|
||||||
return sdev->queue_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pqi_change_queue_type(struct scsi_device *sdev, int tag_type)
|
|
||||||
{
|
|
||||||
if (sdev->tagged_supported) {
|
|
||||||
scsi_set_tag_type(sdev, tag_type);
|
|
||||||
if (tag_type)
|
|
||||||
scsi_activate_tcq(sdev, sdev->queue_depth);
|
|
||||||
else
|
|
||||||
scsi_deactivate_tcq(sdev, sdev->queue_depth);
|
|
||||||
} else {
|
|
||||||
tag_type = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tag_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH */
|
|
||||||
|
|
||||||
void pqi_compat_init_scsi_host_template(struct scsi_host_template *hostt)
|
|
||||||
{
|
|
||||||
#if !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH
|
|
||||||
hostt->change_queue_depth = pqi_change_queue_depth;
|
|
||||||
hostt->change_queue_type = pqi_change_queue_type;
|
|
||||||
#endif /* !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH */
|
|
||||||
#if KFEATURE_HAS_LOCKLESS_DISPATCH_IO
|
|
||||||
hostt->lockless = 1;
|
|
||||||
#endif
|
|
||||||
#if KFEATURE_HAS_USE_CLUSTERING
|
|
||||||
hostt->use_clustering = ENABLE_CLUSTERING;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void pqi_compat_init_scsi_host(struct Scsi_Host *shost,
|
|
||||||
struct pqi_ctrl_info *ctrl_info)
|
|
||||||
{
|
|
||||||
#if KFEATURE_HAS_MQ_SUPPORT
|
|
||||||
shost->nr_hw_queues = ctrl_info->num_queue_groups;
|
|
||||||
#endif /* KFEATURE_HAS_MQ_SUPPORT */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING
|
|
||||||
|
|
||||||
void scsi_sanitize_inquiry_string(unsigned char *s, int len)
|
|
||||||
{
|
|
||||||
bool terminated = false;
|
|
||||||
|
|
||||||
for (; len > 0; (--len, ++s)) {
|
|
||||||
if (*s == 0)
|
|
||||||
terminated = true;
|
|
||||||
if (terminated || *s < 0x20 || *s > 0x7e)
|
|
||||||
*s = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT
|
|
||||||
|
|
||||||
#if defined(RHEL6U3)
|
|
||||||
/*
|
|
||||||
* Note that these accessor functions are only for the "PCI Express
|
|
||||||
* Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the
|
|
||||||
* other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.)
|
|
||||||
*/
|
|
||||||
int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
*val = 0;
|
|
||||||
if (pos & 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
|
|
||||||
/*
|
|
||||||
* Reset *val to 0 if pci_read_config_word() fails, it may
|
|
||||||
* have been written as 0xFFFF if hardware error happens
|
|
||||||
* during pci_read_config_word().
|
|
||||||
*/
|
|
||||||
if (ret)
|
|
||||||
*val = 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
|
|
||||||
{
|
|
||||||
if (pos & 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* RHEL6U3 */
|
|
||||||
|
|
||||||
int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
|
|
||||||
u16 clear, u16 set)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
u16 val;
|
|
||||||
|
|
||||||
ret = pcie_capability_read_word(dev, pos, &val);
|
|
||||||
if (!ret) {
|
|
||||||
val &= ~clear;
|
|
||||||
val |= set;
|
|
||||||
ret = pcie_capability_write_word(dev, pos, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_BSG_JOB_SMP_HANDLER
|
|
||||||
|
|
||||||
static int pqi_bsg_map_buffer(struct bsg_buffer *buf, struct request *req)
|
|
||||||
{
|
|
||||||
size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
|
|
||||||
|
|
||||||
if (!req->nr_phys_segments) {
|
|
||||||
WARN_ON(!req->nr_phys_segments);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf->sg_list = kzalloc(sz, GFP_KERNEL);
|
|
||||||
if (!buf->sg_list)
|
|
||||||
return -ENOMEM;
|
|
||||||
sg_init_table(buf->sg_list, req->nr_phys_segments);
|
|
||||||
buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
|
|
||||||
buf->payload_len = blk_rq_bytes(req);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pqi_bsg_prepare_job(struct bsg_job *job, struct request *rq)
|
|
||||||
{
|
|
||||||
struct request *rsp = rq->next_rq;
|
|
||||||
int ret;
|
|
||||||
#if KFEATURE_HAS_SCSI_REQUEST
|
|
||||||
struct scsi_request *req = scsi_req(rq);
|
|
||||||
#else
|
|
||||||
struct request *req = rq;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
job->request = req->cmd;
|
|
||||||
job->request_len = req->cmd_len;
|
|
||||||
job->reply = req->sense;
|
|
||||||
|
|
||||||
if (rq->bio) {
|
|
||||||
ret = pqi_bsg_map_buffer(&job->request_payload, rq);
|
|
||||||
if (ret)
|
|
||||||
goto failjob_rls_job;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp && rsp->bio) {
|
|
||||||
ret = pqi_bsg_map_buffer(&job->reply_payload, rsp);
|
|
||||||
if (ret)
|
|
||||||
goto failjob_rls_rqst_payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
failjob_rls_rqst_payload:
|
|
||||||
kfree(job->request_payload.sg_list);
|
|
||||||
failjob_rls_job:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bsg_return_data {
|
|
||||||
int result;
|
|
||||||
unsigned int reply_payload_rcv_len;
|
|
||||||
};
|
|
||||||
static struct bsg_return_data bsg_ret;
|
|
||||||
|
|
||||||
void pqi_bsg_job_done(struct bsg_job *job, int result,
|
|
||||||
unsigned int reply_payload_rcv_len)
|
|
||||||
{
|
|
||||||
bsg_ret.result = result;
|
|
||||||
bsg_ret.reply_payload_rcv_len = reply_payload_rcv_len;
|
|
||||||
complete(job->dd_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int pqi_sas_smp_handler_compat(struct Scsi_Host *shost, struct sas_rphy *rphy,
|
|
||||||
struct request *rq)
|
|
||||||
{
|
|
||||||
struct bsg_job *job;
|
|
||||||
struct completion bsg_job;
|
|
||||||
#if KFEATURE_HAS_SCSI_REQUEST
|
|
||||||
struct scsi_request *req = scsi_req(rq);
|
|
||||||
struct scsi_request *resp = scsi_req(rq->next_rq);
|
|
||||||
#else
|
|
||||||
struct request *req = rq;
|
|
||||||
struct request *resp = req->next_rq;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
init_completion(&bsg_job);
|
|
||||||
job = kzalloc(sizeof(struct bsg_job), GFP_KERNEL);
|
|
||||||
if (!job)
|
|
||||||
return -ENOMEM;
|
|
||||||
job->dd_data = &bsg_job;
|
|
||||||
|
|
||||||
pqi_bsg_prepare_job(job, rq);
|
|
||||||
pqi_sas_smp_handler(job, shost, rphy);
|
|
||||||
|
|
||||||
wait_for_completion(&bsg_job);
|
|
||||||
|
|
||||||
req->sense_len = job->reply_len;
|
|
||||||
memcpy(req->sense, job->reply, job->reply_len);
|
|
||||||
|
|
||||||
resp->resid_len -= min(bsg_ret.reply_payload_rcv_len, resp->resid_len);
|
|
||||||
req->resid_len = 0;
|
|
||||||
|
|
||||||
kfree(job);
|
|
||||||
return bsg_ret.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_BSG_JOB_SMP_HANDLER */
|
|
||||||
|
|
@ -1,608 +0,0 @@
|
||||||
/*
|
|
||||||
* driver for Microchip PQI-based storage controllers
|
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_SMARTPQI_KERNEL_COMPAT_H)
|
|
||||||
#define _SMARTPQI_KERNEL_COMPAT_H
|
|
||||||
|
|
||||||
/* #define RHEL6 */
|
|
||||||
/* #define RHEL7 */
|
|
||||||
/* default is kernel.org */
|
|
||||||
|
|
||||||
/* ----- RHEL6 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(RHEL6U0) || \
|
|
||||||
defined(RHEL6U1) || \
|
|
||||||
defined(RHEL6U2) || \
|
|
||||||
defined(RHEL6U3) || \
|
|
||||||
defined(RHEL6U4) || \
|
|
||||||
defined(RHEL6U5) || \
|
|
||||||
defined(RHEL6U6) || \
|
|
||||||
defined(RHEL6U7) || \
|
|
||||||
defined(RHEL6U8) || \
|
|
||||||
defined(RHEL6U9) || \
|
|
||||||
defined(RHEL6U10)
|
|
||||||
#define RHEL6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----- RHEL7 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(RHEL7U0) || \
|
|
||||||
defined(RHEL7U1) || \
|
|
||||||
defined(RHEL7U2) || \
|
|
||||||
defined(RHEL7U3) || \
|
|
||||||
defined(RHEL7U4) || \
|
|
||||||
defined(RHEL7U4ARM) || \
|
|
||||||
defined(RHEL7U5) || \
|
|
||||||
defined(RHEL7U5ARM) || \
|
|
||||||
defined(RHEL7U6) || \
|
|
||||||
defined(RHEL7U7) || \
|
|
||||||
defined(RHEL7U8) || \
|
|
||||||
defined(RHEL7U9)
|
|
||||||
#define RHEL7
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----- RHEL8 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(RHEL8U0) || \
|
|
||||||
defined(RHEL8U1) || \
|
|
||||||
defined(RHEL8U2) || \
|
|
||||||
defined(RHEL8U3) || \
|
|
||||||
defined(RHEL8U4) || \
|
|
||||||
defined(RHEL8U5) || \
|
|
||||||
defined(RHEL8U6) || \
|
|
||||||
defined(RHEL8U7)
|
|
||||||
#define RHEL8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----- SLES11 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(SLES11SP0) || \
|
|
||||||
defined(SLES11SP1) || \
|
|
||||||
defined(SLES11SP2) || \
|
|
||||||
defined(SLES11SP3) || \
|
|
||||||
defined(SLES11SP4)
|
|
||||||
#define SLES11
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----- SLES12 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(SLES12SP0) || \
|
|
||||||
defined(SLES12SP1) || \
|
|
||||||
defined(SLES12SP2) || \
|
|
||||||
defined(SLES12SP3) || \
|
|
||||||
defined(SLES12SP4) || \
|
|
||||||
defined(SLES12SP5)
|
|
||||||
#define SLES12
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----- SLES15 variants --------- */
|
|
||||||
#if \
|
|
||||||
defined(SLES15SP0) || \
|
|
||||||
defined(SLES15SP1) || \
|
|
||||||
defined(SLES15SP2) || \
|
|
||||||
defined(SLES15SP3) || \
|
|
||||||
defined(SLES15SP4)
|
|
||||||
#define SLES15
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <scsi/scsi_tcq.h>
|
|
||||||
#include <linux/bsg-lib.h>
|
|
||||||
#include <linux/ktime.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
|
|
||||||
#if defined(MSG_SIMPLE_TAG)
|
|
||||||
#define KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH 0
|
|
||||||
#if !defined(RHEL7U3)
|
|
||||||
#define KFEATURE_HAS_MQ_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RHEL8) || defined(CENTOS7ALTARM)
|
|
||||||
#define KFEATURE_HAS_MQ_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(XEN7)
|
|
||||||
#define KCLASS4A
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_EXP_DEVCTL2_COMP_TIMEOUT)
|
|
||||||
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f
|
|
||||||
#if TORTUGA
|
|
||||||
#define KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT 1
|
|
||||||
#else
|
|
||||||
#define KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RHEL6)
|
|
||||||
#define KFEATURE_HAS_WAIT_FOR_COMPLETION_IO 0
|
|
||||||
#define KFEATURE_HAS_2011_03_QUEUECOMMAND 0
|
|
||||||
#define KFEATURE_HAS_NO_WRITE_SAME 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#if defined(RHEL6U3) || defined(RHEL6U4) || defined(RHEL6U5)
|
|
||||||
#if defined(RHEL6U3)
|
|
||||||
#define KFEATURE_HAS_DMA_ZALLOC_COHERENT 0
|
|
||||||
#endif
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 0
|
|
||||||
#endif
|
|
||||||
#if !defined(RHEL6U0) && !defined(RHEL6U1)
|
|
||||||
#define KFEATURE_HAS_LOCKLESS_DISPATCH_IO 1
|
|
||||||
#endif
|
|
||||||
#if defined(RHEL6U5)
|
|
||||||
#define KFEATURE_HAS_DMA_MASK_AND_COHERENT 0
|
|
||||||
#endif
|
|
||||||
#elif defined(RHEL7)
|
|
||||||
#if defined(RHEL7U0)
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#endif
|
|
||||||
#if defined(RHEL7U1)
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#endif
|
|
||||||
#if defined(RHEL7U4ARM) || defined(RHEL7U5ARM)
|
|
||||||
#endif
|
|
||||||
#elif defined(SLES11)
|
|
||||||
#define KFEATURE_HAS_WAIT_FOR_COMPLETION_IO 0
|
|
||||||
#define KFEATURE_HAS_NO_WRITE_SAME 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#if defined(SLES11SP0) || defined(SLES11SP1)
|
|
||||||
#define KFEATURE_HAS_2011_03_QUEUECOMMAND 0
|
|
||||||
#endif
|
|
||||||
#if defined(SLES11SP3)
|
|
||||||
#define KFEATURE_HAS_DMA_ZALLOC_COHERENT 0
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 0
|
|
||||||
#endif
|
|
||||||
#elif defined(SLES12)
|
|
||||||
#if defined(SLES12SP2) || defined(SLES12SP3)
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#endif
|
|
||||||
#if defined(SLES12SP0)
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#endif
|
|
||||||
#if defined(SLES12SP1)
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#endif
|
|
||||||
#elif defined(SLES15)
|
|
||||||
#define KFEATURE_HAS_SCSI_REQUEST 1
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#elif defined(UBUNTU1404) || TORTUGA || defined(KCLASS3C)
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#elif defined(OL7U2) || defined(KCLASS3B)
|
|
||||||
#define KFEATURE_HAS_DMA_MASK_AND_COHERENT 0
|
|
||||||
#define KFEATURE_HAS_WAIT_FOR_COMPLETION_IO 0
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 0
|
|
||||||
#endif
|
|
||||||
#if defined(KCLASS4A)
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#endif
|
|
||||||
#if defined(KCLASS4B) || defined(KCLASS4C) || defined(SLES12SP4) || \
|
|
||||||
defined(SLES12SP5) || defined(RHEL8) || defined(KCLASS5A) || \
|
|
||||||
defined(KCLASS5B) || defined(KCLASS5C) || defined(KCLASS5D) || \
|
|
||||||
defined(SLES15SP2) || defined(SLES15SP3) || defined (CENTOS7ALTARM)
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#define KFEATURE_HAS_SCSI_REQUEST 1
|
|
||||||
#define KFEATURE_HAS_KTIME64 1
|
|
||||||
#endif
|
|
||||||
#if defined(KCLASS4C) || defined(RHEL8) || defined(SLES15SP1) || \
|
|
||||||
defined(SLES15SP2) || defined(SLES15SP3) || defined(KCLASS5A) || \
|
|
||||||
defined(KCLASS5B) || defined(KCLASS5C) || defined(KCLASS5D) || \
|
|
||||||
defined(SLES12SP5) || defined (CENTOS7ALTARM)
|
|
||||||
#define KFEATURE_HAS_BSG_JOB_SMP_HANDLER 1
|
|
||||||
#endif
|
|
||||||
#if defined(RHEL8U3)
|
|
||||||
#define KFEATURE_HAS_HOST_BUSY_FUNCTION 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KCLASS3D)
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#endif
|
|
||||||
#if defined(KCLASS5A) || defined(KCLASS5B) || defined(KCLASS5C) || defined(KCLASS5D) || \
|
|
||||||
defined(KCLASS4D) || defined(SLES15SP2) || defined(SLES15SP3)
|
|
||||||
#define dma_zalloc_coherent dma_alloc_coherent
|
|
||||||
#define shost_use_blk_mq(x) 1
|
|
||||||
#define KFEATURE_HAS_USE_CLUSTERING 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KCLASS5B) || defined(KCLASS5C) || defined(KCLASS5D) || \
|
|
||||||
defined(KCLASS4D) || defined(SLES15SP2) || defined(SLES15SP3)
|
|
||||||
#define IOCTL_INT unsigned int
|
|
||||||
#else
|
|
||||||
#define IOCTL_INT int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(KCLASS5C) || defined(KCLASS5D)
|
|
||||||
#define KFEATURE_HAS_HOST_BUSY_FUNCTION 1
|
|
||||||
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
|
|
||||||
#define ioremap_nocache ioremap
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(from_timer)
|
|
||||||
#define KFEATURE_HAS_OLD_TIMER 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* default values */
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 1
|
|
||||||
#define KFEATURE_HAS_BSG_JOB_SMP_HANDLER 1
|
|
||||||
#define KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING 1
|
|
||||||
|
|
||||||
#if !defined(KFEATURE_HAS_WAIT_FOR_COMPLETION_IO)
|
|
||||||
#define KFEATURE_HAS_WAIT_FOR_COMPLETION_IO 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_2011_03_QUEUECOMMAND)
|
|
||||||
#define KFEATURE_HAS_2011_03_QUEUECOMMAND 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_DMA_ZALLOC_COHERENT)
|
|
||||||
#define KFEATURE_HAS_DMA_ZALLOC_COHERENT 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE)
|
|
||||||
#define KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH)
|
|
||||||
#define KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_MQ_SUPPORT)
|
|
||||||
#define KFEATURE_HAS_MQ_SUPPORT 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING)
|
|
||||||
#define KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT)
|
|
||||||
#define KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_NO_WRITE_SAME)
|
|
||||||
#define KFEATURE_HAS_NO_WRITE_SAME 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_BSG_JOB_SMP_HANDLER)
|
|
||||||
#define KFEATURE_HAS_BSG_JOB_SMP_HANDLER 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_HOST_BUSY_FUNCTION)
|
|
||||||
#define KFEATURE_HAS_HOST_BUSY_FUNCTION 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_SCSI_REQUEST)
|
|
||||||
#define KFEATURE_HAS_SCSI_REQUEST 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_LOCKLESS_DISPATCH_IO)
|
|
||||||
#define KFEATURE_HAS_LOCKLESS_DISPATCH_IO 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_USE_CLUSTERING)
|
|
||||||
#define KFEATURE_HAS_USE_CLUSTERING 1
|
|
||||||
#define IOCTL_INT int
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_OLD_TIMER)
|
|
||||||
#define KFEATURE_HAS_OLD_TIMER 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_KTIME_SECONDS)
|
|
||||||
#define KFEATURE_HAS_KTIME_SECONDS 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_KTIME64)
|
|
||||||
#define KFEATURE_HAS_KTIME64 0
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_DMA_MASK_AND_COHERENT)
|
|
||||||
#define KFEATURE_HAS_DMA_MASK_AND_COHERENT 1
|
|
||||||
#endif
|
|
||||||
#if !defined(KFEATURE_HAS_ATOMIC_HOST_BUSY)
|
|
||||||
#define KFEATURE_HAS_ATOMIC_HOST_BUSY 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(list_next_entry)
|
|
||||||
#define list_next_entry(pos, member) \
|
|
||||||
list_entry((pos)->member.next, typeof(*(pos)), member)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(list_first_entry_or_null)
|
|
||||||
#define list_first_entry_or_null(ptr, type, member) \
|
|
||||||
(!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(TYPE_ZBC)
|
|
||||||
#define TYPE_ZBC 0x14
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(readq)
|
|
||||||
#define readq readq
|
|
||||||
static inline u64 readq(const volatile void __iomem *addr)
|
|
||||||
{
|
|
||||||
u32 lower32;
|
|
||||||
u32 upper32;
|
|
||||||
|
|
||||||
lower32 = readl(addr);
|
|
||||||
upper32 = readl(addr + 4);
|
|
||||||
|
|
||||||
return ((u64)upper32 << 32) | lower32;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(writeq)
|
|
||||||
#define writeq writeq
|
|
||||||
static inline void writeq(u64 value, volatile void __iomem *addr)
|
|
||||||
{
|
|
||||||
u32 lower32;
|
|
||||||
u32 upper32;
|
|
||||||
|
|
||||||
lower32 = lower_32_bits(value);
|
|
||||||
upper32 = upper_32_bits(value);
|
|
||||||
|
|
||||||
writel(lower32, addr);
|
|
||||||
writel(upper32, addr + 4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void pqi_disable_write_same(struct scsi_device *sdev)
|
|
||||||
{
|
|
||||||
#if KFEATURE_HAS_NO_WRITE_SAME
|
|
||||||
sdev->no_write_same = 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(PCI_DEVICE_SUB)
|
|
||||||
#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \
|
|
||||||
.vendor = (vend), .device = (dev), \
|
|
||||||
.subvendor = (subvend), .subdevice = (subdev)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_HPE)
|
|
||||||
#define PCI_VENDOR_ID_HPE 0x1590
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_ADVANTECH)
|
|
||||||
#define PCI_VENDOR_ID_ADVANTECH 0x13fe
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_FIBERHOME)
|
|
||||||
#define PCI_VENDOR_ID_FIBERHOME 0x1d8d
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_GIGABYTE)
|
|
||||||
#define PCI_VENDOR_ID_GIGABYTE 0x1458
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_FOXCONN)
|
|
||||||
#define PCI_VENDOR_ID_FOXCONN 0x105b
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_HUAWEI)
|
|
||||||
#define PCI_VENDOR_ID_HUAWEI 0x19e5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_H3C)
|
|
||||||
#define PCI_VENDOR_ID_H3C 0x193d
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_QUANTA)
|
|
||||||
#define PCI_VENDOR_ID_QUANTA 0x152d
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(PCI_VENDOR_ID_INSPUR)
|
|
||||||
#define PCI_VENDOR_ID_INSPUR 0x1bd4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(offsetofend)
|
|
||||||
#define offsetofend(TYPE, MEMBER) \
|
|
||||||
(offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void pqi_compat_init_scsi_host_template(struct scsi_host_template *template);
|
|
||||||
void pqi_compat_init_scsi_host(struct Scsi_Host *shost,
|
|
||||||
struct pqi_ctrl_info *ctrl_info);
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_WAIT_FOR_COMPLETION_IO
|
|
||||||
|
|
||||||
static inline unsigned long wait_for_completion_io_timeout(struct completion *x,
|
|
||||||
unsigned long timeout)
|
|
||||||
{
|
|
||||||
return wait_for_completion_timeout(x, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long wait_for_completion_io(struct completion *x)
|
|
||||||
{
|
|
||||||
wait_for_completion(x);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_WAIT_FOR_COMPLETION_IO */
|
|
||||||
|
|
||||||
#if KFEATURE_HAS_2011_03_QUEUECOMMAND
|
|
||||||
|
|
||||||
#define PQI_SCSI_QUEUE_COMMAND pqi_scsi_queue_command
|
|
||||||
|
|
||||||
static inline void pqi_scsi_done(struct scsi_cmnd *scmd)
|
|
||||||
{
|
|
||||||
pqi_prep_for_scsi_done(scmd);
|
|
||||||
if (scmd && scmd->scsi_done)
|
|
||||||
scmd->scsi_done(scmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
int pqi_scsi_queue_command_compat(struct scsi_cmnd *scmd,
|
|
||||||
void (*done)(struct scsi_cmnd *));
|
|
||||||
|
|
||||||
#define PQI_SCSI_QUEUE_COMMAND pqi_scsi_queue_command_compat
|
|
||||||
|
|
||||||
static inline void pqi_scsi_done(struct scsi_cmnd *scmd)
|
|
||||||
{
|
|
||||||
void (*scsi_done)(struct scsi_cmnd *);
|
|
||||||
|
|
||||||
pqi_prep_for_scsi_done(scmd);
|
|
||||||
if (scmd) {
|
|
||||||
scsi_done = (void(*)(struct scsi_cmnd *))scmd->SCp.ptr;
|
|
||||||
scsi_done(scmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* KFEATURE_HAS_2011_03_QUEUECOMMAND */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_DMA_ZALLOC_COHERENT
|
|
||||||
|
|
||||||
static inline void *dma_zalloc_coherent(struct device *dev, size_t size,
|
|
||||||
dma_addr_t *dma_handle, gfp_t flag)
|
|
||||||
{
|
|
||||||
void *ret = dma_alloc_coherent(dev, size, dma_handle,
|
|
||||||
flag | __GFP_ZERO);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_DMA_ZALLOC_COHERENT */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE
|
|
||||||
|
|
||||||
int pci_enable_msix_range(struct pci_dev *pci_dev, struct msix_entry *entries,
|
|
||||||
int minvec, int maxvec);
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_PCI_ENABLE_MSIX_RANGE */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH
|
|
||||||
|
|
||||||
int scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth);
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_SCSI_CHANGE_QUEUE_DEPTH */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING
|
|
||||||
|
|
||||||
void scsi_sanitize_inquiry_string(unsigned char *s, int len);
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_SCSI_SANITIZE_INQUIRY_STRING */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT
|
|
||||||
|
|
||||||
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
|
|
||||||
|
|
||||||
int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
|
|
||||||
u16 clear, u16 set);
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_PCIE_CAPABILITY_SUPPORT */
|
|
||||||
|
|
||||||
static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info,
|
|
||||||
struct scsi_cmnd *scmd)
|
|
||||||
{
|
|
||||||
u16 hw_queue;
|
|
||||||
|
|
||||||
#if KFEATURE_HAS_MQ_SUPPORT
|
|
||||||
if (shost_use_blk_mq(scmd->device->host))
|
|
||||||
hw_queue = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scmd->request));
|
|
||||||
else
|
|
||||||
hw_queue = smp_processor_id();
|
|
||||||
#else
|
|
||||||
hw_queue = smp_processor_id();
|
|
||||||
#endif
|
|
||||||
if (hw_queue > ctrl_info->max_hw_queue_index)
|
|
||||||
hw_queue = 0;
|
|
||||||
|
|
||||||
return hw_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef KFEATURE_NEEDS_BLK_RQ_IS_PASSTHROUGH
|
|
||||||
|
|
||||||
static inline bool blk_rq_is_passthrough(struct request *rq)
|
|
||||||
{
|
|
||||||
return rq->cmd_type != REQ_TYPE_FS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* KFEATURE_NEEDS_BLK_RQ_IS_PASSTHROUGH */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_BSG_JOB_SMP_HANDLER
|
|
||||||
|
|
||||||
int pqi_sas_smp_handler_compat(struct Scsi_Host *shost, struct sas_rphy *rphy,
|
|
||||||
struct request *req);
|
|
||||||
|
|
||||||
void pqi_bsg_job_done(struct bsg_job *job, int result,
|
|
||||||
unsigned int reply_payload_rcv_len);
|
|
||||||
|
|
||||||
#define PQI_SAS_SMP_HANDLER pqi_sas_smp_handler_compat
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define PQI_SAS_SMP_HANDLER pqi_sas_smp_handler
|
|
||||||
|
|
||||||
static inline void pqi_bsg_job_done(struct bsg_job *job, int result,
|
|
||||||
unsigned int reply_payload_rcv_len)
|
|
||||||
{
|
|
||||||
bsg_job_done(job, result, reply_payload_rcv_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_BSG_JOB_SMP_HANDLER */
|
|
||||||
|
|
||||||
#if KFEATURE_HAS_OLD_TIMER
|
|
||||||
#define from_timer(var, callback_timer, timer_fieldname) \
|
|
||||||
container_of(callback_timer, typeof(*var), timer_fieldname)
|
|
||||||
|
|
||||||
#if !defined(TIMER_DATA_TYPE)
|
|
||||||
#define TIMER_DATA_TYPE unsigned long
|
|
||||||
#define TIMER_FUNC_TYPE void (*)(TIMER_DATA_TYPE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void timer_setup (struct timer_list *timer,
|
|
||||||
void (*func) (struct timer_list *), unsigned long data)
|
|
||||||
{
|
|
||||||
init_timer(timer);
|
|
||||||
timer->function = (TIMER_FUNC_TYPE) func;
|
|
||||||
timer->data = (unsigned long) timer;
|
|
||||||
}
|
|
||||||
#endif /* KFEATURE_HAS_OLD_TIMER */
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_KTIME64
|
|
||||||
#define time64_to_tm time_to_tm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_KTIME_SECONDS
|
|
||||||
static inline unsigned long ktime_get_real_seconds(void)
|
|
||||||
{
|
|
||||||
ktime_t tv;
|
|
||||||
struct timeval time;
|
|
||||||
|
|
||||||
tv = ktime_get_real();
|
|
||||||
time = ktime_to_timeval(tv);
|
|
||||||
|
|
||||||
return time.tv_sec;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !KFEATURE_HAS_DMA_MASK_AND_COHERENT
|
|
||||||
|
|
||||||
static inline int pqi_dma_set_mask_and_coherent(struct device *device, u64 mask)
|
|
||||||
{
|
|
||||||
return dma_set_mask(device, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline int pqi_dma_set_mask_and_coherent(struct device *device, u64 mask)
|
|
||||||
{
|
|
||||||
return dma_set_mask_and_coherent(device, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !KFEATURE_HAS_DMA_MASK_AND_COHERENT */
|
|
||||||
|
|
||||||
static inline bool pqi_scsi_host_busy(struct Scsi_Host *shost)
|
|
||||||
{
|
|
||||||
#if KFEATURE_HAS_HOST_BUSY_FUNCTION
|
|
||||||
return scsi_host_busy(shost);
|
|
||||||
#else
|
|
||||||
#if KFEATURE_HAS_ATOMIC_HOST_BUSY
|
|
||||||
return atomic_read(&shost->host_busy) > 0;
|
|
||||||
#else
|
|
||||||
return shost->host_busy > 0;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _SMARTPQI_KERNEL_COMPAT_H */
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* driver for Microchip PQI-based storage controllers
|
* driver for Microsemi PQI-based storage controllers
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
* Copyright (c) 2016-2017 Microsemi Corporation
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
* Copyright (c) 2016 PMC-Sierra, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -13,18 +12,15 @@
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
* Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/bsg-lib.h>
|
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_transport_sas.h>
|
#include <scsi/scsi_transport_sas.h>
|
||||||
#include <asm/unaligned.h>
|
|
||||||
#include "smartpqi.h"
|
#include "smartpqi.h"
|
||||||
#include "smartpqi_kernel_compat.h"
|
|
||||||
|
|
||||||
static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port)
|
static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port)
|
||||||
{
|
{
|
||||||
|
|
@ -54,9 +50,9 @@ static void pqi_free_sas_phy(struct pqi_sas_phy *pqi_sas_phy)
|
||||||
struct sas_phy *phy = pqi_sas_phy->phy;
|
struct sas_phy *phy = pqi_sas_phy->phy;
|
||||||
|
|
||||||
sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy);
|
sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy);
|
||||||
|
sas_phy_free(phy);
|
||||||
if (pqi_sas_phy->added_to_port)
|
if (pqi_sas_phy->added_to_port)
|
||||||
list_del(&pqi_sas_phy->phy_list_entry);
|
list_del(&pqi_sas_phy->phy_list_entry);
|
||||||
sas_phy_delete(phy);
|
|
||||||
kfree(pqi_sas_phy);
|
kfree(pqi_sas_phy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,8 +70,8 @@ static int pqi_sas_port_add_phy(struct pqi_sas_phy *pqi_sas_phy)
|
||||||
memset(identify, 0, sizeof(*identify));
|
memset(identify, 0, sizeof(*identify));
|
||||||
identify->sas_address = pqi_sas_port->sas_address;
|
identify->sas_address = pqi_sas_port->sas_address;
|
||||||
identify->device_type = SAS_END_DEVICE;
|
identify->device_type = SAS_END_DEVICE;
|
||||||
identify->initiator_port_protocols = SAS_PROTOCOL_ALL;
|
identify->initiator_port_protocols = SAS_PROTOCOL_STP;
|
||||||
identify->target_port_protocols = SAS_PROTOCOL_ALL;
|
identify->target_port_protocols = SAS_PROTOCOL_STP;
|
||||||
phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
|
phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
|
||||||
phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
|
phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN;
|
||||||
phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN;
|
phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN;
|
||||||
|
|
@ -101,42 +97,14 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port,
|
||||||
|
|
||||||
identify = &rphy->identify;
|
identify = &rphy->identify;
|
||||||
identify->sas_address = pqi_sas_port->sas_address;
|
identify->sas_address = pqi_sas_port->sas_address;
|
||||||
identify->phy_identifier = pqi_sas_port->device->phy_id;
|
identify->initiator_port_protocols = SAS_PROTOCOL_STP;
|
||||||
|
|
||||||
identify->initiator_port_protocols = SAS_PROTOCOL_ALL;
|
|
||||||
identify->target_port_protocols = SAS_PROTOCOL_STP;
|
identify->target_port_protocols = SAS_PROTOCOL_STP;
|
||||||
|
|
||||||
if (pqi_sas_port->device) {
|
|
||||||
switch (pqi_sas_port->device->device_type) {
|
|
||||||
case SA_DEVICE_TYPE_SAS:
|
|
||||||
case SA_DEVICE_TYPE_SES:
|
|
||||||
case SA_DEVICE_TYPE_NVME:
|
|
||||||
identify->target_port_protocols = SAS_PROTOCOL_SSP;
|
|
||||||
break;
|
|
||||||
case SA_DEVICE_TYPE_EXPANDER_SMP:
|
|
||||||
identify->target_port_protocols = SAS_PROTOCOL_SMP;
|
|
||||||
break;
|
|
||||||
case SA_DEVICE_TYPE_SATA:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sas_rphy_add(rphy);
|
return sas_rphy_add(rphy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sas_rphy *pqi_sas_rphy_alloc(struct pqi_sas_port *pqi_sas_port)
|
|
||||||
{
|
|
||||||
if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device)
|
|
||||||
return sas_expander_alloc(pqi_sas_port->port,
|
|
||||||
SAS_FANOUT_EXPANDER_DEVICE);
|
|
||||||
|
|
||||||
return sas_end_device_alloc(pqi_sas_port->port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pqi_sas_port *pqi_alloc_sas_port(
|
static struct pqi_sas_port *pqi_alloc_sas_port(
|
||||||
struct pqi_sas_node *pqi_sas_node, u64 sas_address,
|
struct pqi_sas_node *pqi_sas_node, u64 sas_address)
|
||||||
struct pqi_scsi_dev *device)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct pqi_sas_port *pqi_sas_port;
|
struct pqi_sas_port *pqi_sas_port;
|
||||||
|
|
@ -159,7 +127,6 @@ static struct pqi_sas_port *pqi_alloc_sas_port(
|
||||||
|
|
||||||
pqi_sas_port->port = port;
|
pqi_sas_port->port = port;
|
||||||
pqi_sas_port->sas_address = sas_address;
|
pqi_sas_port->sas_address = sas_address;
|
||||||
pqi_sas_port->device = device;
|
|
||||||
list_add_tail(&pqi_sas_port->port_list_entry,
|
list_add_tail(&pqi_sas_port->port_list_entry,
|
||||||
&pqi_sas_node->port_list_head);
|
&pqi_sas_node->port_list_head);
|
||||||
|
|
||||||
|
|
@ -179,8 +146,8 @@ static void pqi_free_sas_port(struct pqi_sas_port *pqi_sas_port)
|
||||||
struct pqi_sas_phy *next;
|
struct pqi_sas_phy *next;
|
||||||
|
|
||||||
list_for_each_entry_safe(pqi_sas_phy, next,
|
list_for_each_entry_safe(pqi_sas_phy, next,
|
||||||
&pqi_sas_port->phy_list_head, phy_list_entry)
|
&pqi_sas_port->phy_list_head, phy_list_entry)
|
||||||
pqi_free_sas_phy(pqi_sas_phy);
|
pqi_free_sas_phy(pqi_sas_phy);
|
||||||
|
|
||||||
sas_port_delete(pqi_sas_port->port);
|
sas_port_delete(pqi_sas_port->port);
|
||||||
list_del(&pqi_sas_port->port_list_entry);
|
list_del(&pqi_sas_port->port_list_entry);
|
||||||
|
|
@ -209,8 +176,8 @@ static void pqi_free_sas_node(struct pqi_sas_node *pqi_sas_node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_entry_safe(pqi_sas_port, next,
|
list_for_each_entry_safe(pqi_sas_port, next,
|
||||||
&pqi_sas_node->port_list_head, port_list_entry)
|
&pqi_sas_node->port_list_head, port_list_entry)
|
||||||
pqi_free_sas_port(pqi_sas_port);
|
pqi_free_sas_port(pqi_sas_port);
|
||||||
|
|
||||||
kfree(pqi_sas_node);
|
kfree(pqi_sas_node);
|
||||||
}
|
}
|
||||||
|
|
@ -239,14 +206,13 @@ int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info)
|
||||||
struct pqi_sas_port *pqi_sas_port;
|
struct pqi_sas_port *pqi_sas_port;
|
||||||
struct pqi_sas_phy *pqi_sas_phy;
|
struct pqi_sas_phy *pqi_sas_phy;
|
||||||
|
|
||||||
parent_dev = &shost->shost_dev;
|
parent_dev = &shost->shost_gendev;
|
||||||
|
|
||||||
pqi_sas_node = pqi_alloc_sas_node(parent_dev);
|
pqi_sas_node = pqi_alloc_sas_node(parent_dev);
|
||||||
if (!pqi_sas_node)
|
if (!pqi_sas_node)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
|
pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node, ctrl_info->sas_address);
|
||||||
ctrl_info->sas_address, NULL);
|
|
||||||
if (!pqi_sas_port) {
|
if (!pqi_sas_port) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto free_sas_node;
|
goto free_sas_node;
|
||||||
|
|
@ -288,12 +254,11 @@ int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
|
||||||
struct pqi_sas_port *pqi_sas_port;
|
struct pqi_sas_port *pqi_sas_port;
|
||||||
struct sas_rphy *rphy;
|
struct sas_rphy *rphy;
|
||||||
|
|
||||||
pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
|
pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node, device->sas_address);
|
||||||
device->sas_address, device);
|
|
||||||
if (!pqi_sas_port)
|
if (!pqi_sas_port)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rphy = pqi_sas_rphy_alloc(pqi_sas_port);
|
rphy = sas_end_device_alloc(pqi_sas_port->port);
|
||||||
if (!rphy) {
|
if (!rphy) {
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
goto free_sas_port;
|
goto free_sas_port;
|
||||||
|
|
@ -331,107 +296,12 @@ static int pqi_sas_get_linkerrors(struct sas_phy *phy)
|
||||||
static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy,
|
static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy,
|
||||||
u64 *identifier)
|
u64 *identifier)
|
||||||
{
|
{
|
||||||
int rc;
|
return 0;
|
||||||
unsigned long flags;
|
|
||||||
struct Scsi_Host *shost;
|
|
||||||
struct pqi_ctrl_info *ctrl_info;
|
|
||||||
struct pqi_scsi_dev *found_device;
|
|
||||||
struct pqi_scsi_dev *device;
|
|
||||||
|
|
||||||
if (!rphy)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
shost = rphy_to_shost(rphy);
|
|
||||||
ctrl_info = shost_to_hba(shost);
|
|
||||||
spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
|
|
||||||
found_device = pqi_find_device_by_sas_rphy(ctrl_info, rphy);
|
|
||||||
|
|
||||||
if (!found_device) {
|
|
||||||
rc = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_device->devtype == TYPE_ENCLOSURE) {
|
|
||||||
*identifier = get_unaligned_be64(&found_device->wwid);
|
|
||||||
rc = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_device->box_index == 0xff ||
|
|
||||||
found_device->phys_box_on_bus == 0 ||
|
|
||||||
found_device->bay == 0xff) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(device, &ctrl_info->scsi_device_list,
|
|
||||||
scsi_device_list_entry) {
|
|
||||||
if (device->devtype == TYPE_ENCLOSURE &&
|
|
||||||
device->box_index == found_device->box_index &&
|
|
||||||
device->phys_box_on_bus ==
|
|
||||||
found_device->phys_box_on_bus &&
|
|
||||||
memcmp(device->phys_connector,
|
|
||||||
found_device->phys_connector, 2) == 0) {
|
|
||||||
*identifier =
|
|
||||||
get_unaligned_be64(&device->wwid);
|
|
||||||
rc = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_device->phy_connected_dev_type != SA_DEVICE_TYPE_CONTROLLER) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(device, &ctrl_info->scsi_device_list,
|
|
||||||
scsi_device_list_entry) {
|
|
||||||
if (device->devtype == TYPE_ENCLOSURE &&
|
|
||||||
CISS_GET_DRIVE_NUMBER(device->scsi3addr) ==
|
|
||||||
PQI_VSEP_CISS_BTL) {
|
|
||||||
*identifier = get_unaligned_be64(&device->wwid);
|
|
||||||
rc = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = -EINVAL;
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pqi_sas_get_bay_identifier(struct sas_rphy *rphy)
|
static int pqi_sas_get_bay_identifier(struct sas_rphy *rphy)
|
||||||
{
|
{
|
||||||
int rc;
|
return -ENXIO;
|
||||||
unsigned long flags;
|
|
||||||
struct pqi_ctrl_info *ctrl_info;
|
|
||||||
struct pqi_scsi_dev *device;
|
|
||||||
struct Scsi_Host *shost;
|
|
||||||
|
|
||||||
if (!rphy)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
shost = rphy_to_shost(rphy);
|
|
||||||
ctrl_info = shost_to_hba(shost);
|
|
||||||
spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
|
|
||||||
device = pqi_find_device_by_sas_rphy(ctrl_info, rphy);
|
|
||||||
|
|
||||||
if (!device) {
|
|
||||||
rc = -ENODEV;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->bay == 0xff)
|
|
||||||
rc = -EINVAL;
|
|
||||||
else
|
|
||||||
rc = device->bay;
|
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pqi_sas_phy_reset(struct sas_phy *phy, int hard_reset)
|
static int pqi_sas_phy_reset(struct sas_phy *phy, int hard_reset)
|
||||||
|
|
@ -459,118 +329,6 @@ static int pqi_sas_phy_speed(struct sas_phy *phy,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CSMI_IOCTL_TIMEOUT 60
|
|
||||||
#define SMP_CRC_FIELD_LENGTH 4
|
|
||||||
|
|
||||||
static struct bmic_csmi_smp_passthru_buffer *
|
|
||||||
pqi_build_csmi_smp_passthru_buffer(struct sas_rphy *rphy,
|
|
||||||
struct bsg_job *job)
|
|
||||||
{
|
|
||||||
struct bmic_csmi_smp_passthru_buffer *smp_buf;
|
|
||||||
struct bmic_csmi_ioctl_header *ioctl_header;
|
|
||||||
struct bmic_csmi_smp_passthru *parameters;
|
|
||||||
u32 req_size;
|
|
||||||
u32 resp_size;
|
|
||||||
|
|
||||||
smp_buf = kzalloc(sizeof(*smp_buf), GFP_KERNEL);
|
|
||||||
if (!smp_buf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
req_size = job->request_payload.payload_len;
|
|
||||||
resp_size = job->reply_payload.payload_len;
|
|
||||||
|
|
||||||
ioctl_header = &smp_buf->ioctl_header;
|
|
||||||
put_unaligned_le32(sizeof(smp_buf->ioctl_header),
|
|
||||||
&ioctl_header->header_length);
|
|
||||||
put_unaligned_le32(CSMI_IOCTL_TIMEOUT, &ioctl_header->timeout);
|
|
||||||
put_unaligned_le32(CSMI_CC_SAS_SMP_PASSTHRU,
|
|
||||||
&ioctl_header->control_code);
|
|
||||||
put_unaligned_le32(sizeof(smp_buf->parameters), &ioctl_header->length);
|
|
||||||
|
|
||||||
parameters = &smp_buf->parameters;
|
|
||||||
parameters->phy_identifier = rphy->identify.phy_identifier;
|
|
||||||
parameters->port_identifier = 0;
|
|
||||||
parameters->connection_rate = 0;
|
|
||||||
put_unaligned_be64(rphy->identify.sas_address,
|
|
||||||
¶meters->destination_sas_address);
|
|
||||||
|
|
||||||
if (req_size > SMP_CRC_FIELD_LENGTH)
|
|
||||||
req_size -= SMP_CRC_FIELD_LENGTH;
|
|
||||||
|
|
||||||
put_unaligned_le32(req_size, ¶meters->request_length);
|
|
||||||
put_unaligned_le32(resp_size, ¶meters->response_length);
|
|
||||||
|
|
||||||
sg_copy_to_buffer(job->request_payload.sg_list,
|
|
||||||
job->reply_payload.sg_cnt, ¶meters->request,
|
|
||||||
req_size);
|
|
||||||
|
|
||||||
return smp_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int pqi_build_sas_smp_handler_reply(
|
|
||||||
struct bmic_csmi_smp_passthru_buffer *smp_buf, struct bsg_job *job,
|
|
||||||
struct pqi_raid_error_info *error_info)
|
|
||||||
{
|
|
||||||
sg_copy_from_buffer(job->reply_payload.sg_list,
|
|
||||||
job->reply_payload.sg_cnt, &smp_buf->parameters.response,
|
|
||||||
le32_to_cpu(smp_buf->parameters.response_length));
|
|
||||||
|
|
||||||
job->reply_len = le16_to_cpu(error_info->sense_data_length);
|
|
||||||
memcpy(job->reply, error_info->data,
|
|
||||||
le16_to_cpu(error_info->sense_data_length));
|
|
||||||
|
|
||||||
return job->reply_payload.payload_len -
|
|
||||||
get_unaligned_le32(&error_info->data_in_transferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
|
|
||||||
struct sas_rphy *rphy)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
struct pqi_ctrl_info *ctrl_info;
|
|
||||||
struct bmic_csmi_smp_passthru_buffer *smp_buf;
|
|
||||||
struct pqi_raid_error_info error_info;
|
|
||||||
unsigned int reslen = 0;
|
|
||||||
|
|
||||||
ctrl_info = shost_to_hba(shost);
|
|
||||||
|
|
||||||
if (job->reply_payload.payload_len == 0) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rphy) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rphy->identify.device_type != SAS_FANOUT_EXPANDER_DEVICE) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job->request_payload.sg_cnt > 1 || job->reply_payload.sg_cnt > 1) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
smp_buf = pqi_build_csmi_smp_passthru_buffer(rphy, job);
|
|
||||||
if (!smp_buf) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = pqi_csmi_smp_passthru(ctrl_info, smp_buf, sizeof(*smp_buf),
|
|
||||||
&error_info);
|
|
||||||
if (rc)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
reslen = pqi_build_sas_smp_handler_reply(smp_buf, job, &error_info);
|
|
||||||
|
|
||||||
out:
|
|
||||||
pqi_bsg_job_done(job, rc, reslen);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sas_function_template pqi_sas_transport_functions = {
|
struct sas_function_template pqi_sas_transport_functions = {
|
||||||
.get_linkerrors = pqi_sas_get_linkerrors,
|
.get_linkerrors = pqi_sas_get_linkerrors,
|
||||||
.get_enclosure_identifier = pqi_sas_get_enclosure_identifier,
|
.get_enclosure_identifier = pqi_sas_get_enclosure_identifier,
|
||||||
|
|
@ -580,6 +338,4 @@ struct sas_function_template pqi_sas_transport_functions = {
|
||||||
.phy_setup = pqi_sas_phy_setup,
|
.phy_setup = pqi_sas_phy_setup,
|
||||||
.phy_release = pqi_sas_phy_release,
|
.phy_release = pqi_sas_phy_release,
|
||||||
.set_phy_speed = pqi_sas_phy_speed,
|
.set_phy_speed = pqi_sas_phy_speed,
|
||||||
.smp_handler = PQI_SAS_SMP_HANDLER,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* driver for Microchip PQI-based storage controllers
|
* driver for Microsemi PQI-based storage controllers
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
* Copyright (c) 2016-2017 Microsemi Corporation
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
* Copyright (c) 2016 PMC-Sierra, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -13,7 +12,7 @@
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
* Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -35,7 +34,6 @@
|
||||||
#define SIS_REENABLE_SIS_MODE 0x1
|
#define SIS_REENABLE_SIS_MODE 0x1
|
||||||
#define SIS_ENABLE_MSIX 0x40
|
#define SIS_ENABLE_MSIX 0x40
|
||||||
#define SIS_ENABLE_INTX 0x80
|
#define SIS_ENABLE_INTX 0x80
|
||||||
#define SIS_SOFT_RESET 0x100
|
|
||||||
#define SIS_CMD_READY 0x200
|
#define SIS_CMD_READY 0x200
|
||||||
#define SIS_TRIGGER_SHUTDOWN 0x800000
|
#define SIS_TRIGGER_SHUTDOWN 0x800000
|
||||||
#define SIS_PQI_RESET_QUIESCE 0x1000000
|
#define SIS_PQI_RESET_QUIESCE 0x1000000
|
||||||
|
|
@ -61,11 +59,7 @@
|
||||||
|
|
||||||
#define SIS_CTRL_KERNEL_UP 0x80
|
#define SIS_CTRL_KERNEL_UP 0x80
|
||||||
#define SIS_CTRL_KERNEL_PANIC 0x100
|
#define SIS_CTRL_KERNEL_PANIC 0x100
|
||||||
#if TORTUGA
|
|
||||||
#define SIS_CTRL_READY_TIMEOUT_SECS 150
|
|
||||||
#else
|
|
||||||
#define SIS_CTRL_READY_TIMEOUT_SECS 180
|
#define SIS_CTRL_READY_TIMEOUT_SECS 180
|
||||||
#endif
|
|
||||||
#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS 90
|
#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS 90
|
||||||
#define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10
|
#define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10
|
||||||
|
|
||||||
|
|
@ -83,7 +77,7 @@ struct sis_base_struct {
|
||||||
/* error response data */
|
/* error response data */
|
||||||
__le32 error_buffer_element_length; /* length of each PQI error */
|
__le32 error_buffer_element_length; /* length of each PQI error */
|
||||||
/* response buffer element */
|
/* response buffer element */
|
||||||
/* in bytes */
|
/* in bytes */
|
||||||
__le32 error_buffer_num_elements; /* total number of PQI error */
|
__le32 error_buffer_num_elements; /* total number of PQI error */
|
||||||
/* response buffers available */
|
/* response buffers available */
|
||||||
};
|
};
|
||||||
|
|
@ -96,7 +90,7 @@ static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
timeout = (timeout_secs * PQI_HZ) + jiffies;
|
timeout = (timeout_secs * HZ) + jiffies;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
status = readl(&ctrl_info->registers->sis_firmware_status);
|
status = readl(&ctrl_info->registers->sis_firmware_status);
|
||||||
|
|
@ -158,12 +152,7 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
|
||||||
bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
|
bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
|
||||||
{
|
{
|
||||||
return readl(&ctrl_info->registers->sis_firmware_status) &
|
return readl(&ctrl_info->registers->sis_firmware_status) &
|
||||||
SIS_CTRL_KERNEL_UP;
|
SIS_CTRL_KERNEL_UP;
|
||||||
}
|
|
||||||
|
|
||||||
u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info)
|
|
||||||
{
|
|
||||||
return readl(&ctrl_info->registers->sis_product_identifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used for passing command parameters/results when issuing SIS commands */
|
/* used for passing command parameters/results when issuing SIS commands */
|
||||||
|
|
@ -213,7 +202,7 @@ static int sis_send_sync_cmd(struct pqi_ctrl_info *ctrl_info,
|
||||||
* the top of the loop in order to give the controller time to start
|
* the top of the loop in order to give the controller time to start
|
||||||
* processing the command before we start polling.
|
* processing the command before we start polling.
|
||||||
*/
|
*/
|
||||||
timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * PQI_HZ) + jiffies;
|
timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies;
|
||||||
while (1) {
|
while (1) {
|
||||||
msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
|
msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
|
||||||
doorbell = readl(®isters->sis_ctrl_to_host_doorbell);
|
doorbell = readl(®isters->sis_ctrl_to_host_doorbell);
|
||||||
|
|
@ -327,9 +316,9 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
|
||||||
put_unaligned_le32(ctrl_info->max_io_slots,
|
put_unaligned_le32(ctrl_info->max_io_slots,
|
||||||
&base_struct->error_buffer_num_elements);
|
&base_struct->error_buffer_num_elements);
|
||||||
|
|
||||||
bus_address = dma_map_single(&ctrl_info->pci_dev->dev, base_struct,
|
bus_address = pci_map_single(ctrl_info->pci_dev, base_struct,
|
||||||
sizeof(*base_struct), DMA_TO_DEVICE);
|
sizeof(*base_struct), PCI_DMA_TODEVICE);
|
||||||
if (dma_mapping_error(&ctrl_info->pci_dev->dev, bus_address)) {
|
if (pci_dma_mapping_error(ctrl_info->pci_dev, bus_address)) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -342,8 +331,9 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
|
||||||
rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
|
rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
|
||||||
¶ms);
|
¶ms);
|
||||||
|
|
||||||
dma_unmap_single(&ctrl_info->pci_dev->dev, bus_address,
|
pci_unmap_single(ctrl_info->pci_dev, bus_address, sizeof(*base_struct),
|
||||||
sizeof(*base_struct), DMA_TO_DEVICE);
|
PCI_DMA_TODEVICE);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(base_struct_unaligned);
|
kfree(base_struct_unaligned);
|
||||||
|
|
||||||
|
|
@ -359,7 +349,7 @@ static int sis_wait_for_doorbell_bit_to_clear(
|
||||||
u32 doorbell_register;
|
u32 doorbell_register;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
|
|
||||||
timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * PQI_HZ) + jiffies;
|
timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * HZ) + jiffies;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
doorbell_register =
|
doorbell_register =
|
||||||
|
|
@ -378,7 +368,7 @@ static int sis_wait_for_doorbell_bit_to_clear(
|
||||||
rc = -ETIMEDOUT;
|
rc = -ETIMEDOUT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
msleep(1);
|
usleep_range(1000, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -431,12 +421,6 @@ u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info)
|
||||||
return readl(&ctrl_info->registers->sis_driver_scratch);
|
return readl(&ctrl_info->registers->sis_driver_scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
|
|
||||||
{
|
|
||||||
writel(SIS_SOFT_RESET,
|
|
||||||
&ctrl_info->registers->sis_host_to_ctrl_doorbell);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) verify_structures(void)
|
static void __attribute__((unused)) verify_structures(void)
|
||||||
{
|
{
|
||||||
BUILD_BUG_ON(offsetof(struct sis_base_struct,
|
BUILD_BUG_ON(offsetof(struct sis_base_struct,
|
||||||
|
|
@ -453,4 +437,3 @@ static void __attribute__((unused)) verify_structures(void)
|
||||||
error_buffer_num_elements) != 0x14);
|
error_buffer_num_elements) != 0x14);
|
||||||
BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
|
BUILD_BUG_ON(sizeof(struct sis_base_struct) != 0x18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* driver for Microchip PQI-based storage controllers
|
* driver for Microsemi PQI-based storage controllers
|
||||||
* Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries
|
* Copyright (c) 2016-2017 Microsemi Corporation
|
||||||
* Copyright (c) 2016-2018 Microsemi Corporation
|
|
||||||
* Copyright (c) 2016 PMC-Sierra, Inc.
|
* Copyright (c) 2016 PMC-Sierra, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -13,7 +12,7 @@
|
||||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||||
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
* NON INFRINGEMENT. See the GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* Questions/Comments/Bugfixes to storagedev@microchip.com
|
* Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -34,7 +33,5 @@ int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info);
|
||||||
int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info);
|
int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info);
|
||||||
void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value);
|
void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value);
|
||||||
u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info);
|
u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info);
|
||||||
void sis_soft_reset(struct pqi_ctrl_info *ctrl_info);
|
|
||||||
u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info);
|
|
||||||
|
|
||||||
#endif /* _SMARTPQI_SIS_H */
|
#endif /* _SMARTPQI_SIS_H */
|
||||||
|
|
|
||||||
|
|
@ -758,7 +758,7 @@ static int sr_probe(struct device *dev)
|
||||||
|
|
||||||
dev_set_drvdata(dev, cd);
|
dev_set_drvdata(dev, cd);
|
||||||
disk->flags |= GENHD_FL_REMOVABLE;
|
disk->flags |= GENHD_FL_REMOVABLE;
|
||||||
device_add_disk(&sdev->sdev_gendev, disk, NULL);
|
device_add_disk(&sdev->sdev_gendev, disk);
|
||||||
|
|
||||||
sdev_printk(KERN_DEBUG, sdev,
|
sdev_printk(KERN_DEBUG, sdev,
|
||||||
"Attached scsi CD-ROM %s\n", cd->cdi.name);
|
"Attached scsi CD-ROM %s\n", cd->cdi.name);
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ static void ovl_put_super(struct super_block *sb)
|
||||||
kfree(ufs);
|
kfree(ufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sync real dirty inodes in upper filesystem (if it exists) */
|
||||||
static int ovl_sync_fs(struct super_block *sb, int wait)
|
static int ovl_sync_fs(struct super_block *sb, int wait)
|
||||||
{
|
{
|
||||||
struct ovl_fs *ufs = sb->s_fs_info;
|
struct ovl_fs *ufs = sb->s_fs_info;
|
||||||
|
|
@ -241,13 +242,21 @@ static int ovl_sync_fs(struct super_block *sb, int wait)
|
||||||
if (!ufs->upper_mnt)
|
if (!ufs->upper_mnt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
upper_sb = ufs->upper_mnt->mnt_sb;
|
* If this is a sync(2) call or an emergency sync, all the super blocks
|
||||||
if (!upper_sb->s_op->sync_fs)
|
* will be iterated, including upper_sb, so no need to do anything.
|
||||||
|
*
|
||||||
|
* If this is a syncfs(2) call, then we do need to call
|
||||||
|
* sync_filesystem() on upper_sb, but enough if we do it when being
|
||||||
|
* called with wait == 1.
|
||||||
|
*/
|
||||||
|
if (!wait)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
upper_sb = ufs->upper_mnt->mnt_sb;
|
||||||
|
|
||||||
down_read(&upper_sb->s_umount);
|
down_read(&upper_sb->s_umount);
|
||||||
ret = upper_sb->s_op->sync_fs(upper_sb, wait);
|
ret = sync_filesystem(upper_sb);
|
||||||
up_read(&upper_sb->s_umount);
|
up_read(&upper_sb->s_umount);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -241,12 +241,12 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
|
||||||
goto out_mmput;
|
goto out_mmput;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&mm->arg_lock);
|
down_read(&mm->mmap_sem);
|
||||||
arg_start = mm->arg_start;
|
arg_start = mm->arg_start;
|
||||||
arg_end = mm->arg_end;
|
arg_end = mm->arg_end;
|
||||||
env_start = mm->env_start;
|
env_start = mm->env_start;
|
||||||
env_end = mm->env_end;
|
env_end = mm->env_end;
|
||||||
spin_unlock(&mm->arg_lock);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
BUG_ON(arg_start > arg_end);
|
BUG_ON(arg_start > arg_end);
|
||||||
BUG_ON(env_start > env_end);
|
BUG_ON(env_start > env_end);
|
||||||
|
|
@ -943,10 +943,10 @@ static ssize_t environ_read(struct file *file, char __user *buf,
|
||||||
if (!mmget_not_zero(mm))
|
if (!mmget_not_zero(mm))
|
||||||
goto free;
|
goto free;
|
||||||
|
|
||||||
spin_lock(&mm->arg_lock);
|
down_read(&mm->mmap_sem);
|
||||||
env_start = mm->env_start;
|
env_start = mm->env_start;
|
||||||
env_end = mm->env_end;
|
env_end = mm->env_end;
|
||||||
spin_unlock(&mm->arg_lock);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
size_t this_len, max_len;
|
size_t this_len, max_len;
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,6 @@ static void seq_set_overflow(struct seq_file *m)
|
||||||
|
|
||||||
static void *seq_buf_alloc(unsigned long size)
|
static void *seq_buf_alloc(unsigned long size)
|
||||||
{
|
{
|
||||||
if (unlikely(size > MAX_RW_COUNT))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return kvmalloc(size, GFP_KERNEL);
|
return kvmalloc(size, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,8 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||||
struct xfs_name *name, xfs_ino_t ino,
|
struct xfs_name *name, xfs_ino_t ino,
|
||||||
xfs_fsblock_t *first,
|
xfs_fsblock_t *first,
|
||||||
struct xfs_defer_ops *dfops, xfs_extlen_t tot);
|
struct xfs_defer_ops *dfops, xfs_extlen_t tot);
|
||||||
|
extern bool xfs_dir2_sf_replace_needblock(struct xfs_inode *dp,
|
||||||
|
xfs_ino_t inum);
|
||||||
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
|
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||||
struct xfs_name *name, xfs_ino_t inum,
|
struct xfs_name *name, xfs_ino_t inum,
|
||||||
xfs_fsblock_t *first,
|
xfs_fsblock_t *first,
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue