Skip to content

Commit 0443659

Browse files
emuslndavem330
authored andcommitted
ionic: Add port management commands
The port management commands apply to the physical port associated with the PCI device, which might be shared among several logical interfaces. Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fbfb803 commit 0443659

File tree

5 files changed

+213
-0
lines changed

5 files changed

+213
-0
lines changed

drivers/net/ethernet/pensando/ionic/ionic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,8 @@ int ionic_identify(struct ionic *ionic);
4242
int ionic_init(struct ionic *ionic);
4343
int ionic_reset(struct ionic *ionic);
4444

45+
int ionic_port_identify(struct ionic *ionic);
46+
int ionic_port_init(struct ionic *ionic);
47+
int ionic_port_reset(struct ionic *ionic);
48+
4549
#endif /* _IONIC_H_ */

drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,27 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
138138
goto err_out_teardown;
139139
}
140140

141+
/* Configure the ports */
142+
err = ionic_port_identify(ionic);
143+
if (err) {
144+
dev_err(dev, "Cannot identify port: %d, aborting\n", err);
145+
goto err_out_reset;
146+
}
147+
148+
err = ionic_port_init(ionic);
149+
if (err) {
150+
dev_err(dev, "Cannot init port: %d, aborting\n", err);
151+
goto err_out_reset;
152+
}
153+
141154
err = ionic_devlink_register(ionic);
142155
if (err)
143156
dev_err(dev, "Cannot register devlink: %d\n", err);
144157

145158
return 0;
146159

160+
err_out_reset:
161+
ionic_reset(ionic);
147162
err_out_teardown:
148163
ionic_dev_teardown(ionic);
149164
err_out_unmap_bars:
@@ -170,6 +185,7 @@ static void ionic_remove(struct pci_dev *pdev)
170185
return;
171186

172187
ionic_devlink_unregister(ionic);
188+
ionic_port_reset(ionic);
173189
ionic_reset(ionic);
174190
ionic_dev_teardown(ionic);
175191
ionic_unmap_bars(ionic);

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,95 @@ void ionic_dev_cmd_reset(struct ionic_dev *idev)
134134

135135
ionic_dev_cmd_go(idev, &cmd);
136136
}
137+
138+
/* Port commands */
139+
void ionic_dev_cmd_port_identify(struct ionic_dev *idev)
140+
{
141+
union ionic_dev_cmd cmd = {
142+
.port_init.opcode = IONIC_CMD_PORT_IDENTIFY,
143+
.port_init.index = 0,
144+
};
145+
146+
ionic_dev_cmd_go(idev, &cmd);
147+
}
148+
149+
void ionic_dev_cmd_port_init(struct ionic_dev *idev)
150+
{
151+
union ionic_dev_cmd cmd = {
152+
.port_init.opcode = IONIC_CMD_PORT_INIT,
153+
.port_init.index = 0,
154+
.port_init.info_pa = cpu_to_le64(idev->port_info_pa),
155+
};
156+
157+
ionic_dev_cmd_go(idev, &cmd);
158+
}
159+
160+
void ionic_dev_cmd_port_reset(struct ionic_dev *idev)
161+
{
162+
union ionic_dev_cmd cmd = {
163+
.port_reset.opcode = IONIC_CMD_PORT_RESET,
164+
.port_reset.index = 0,
165+
};
166+
167+
ionic_dev_cmd_go(idev, &cmd);
168+
}
169+
170+
void ionic_dev_cmd_port_state(struct ionic_dev *idev, u8 state)
171+
{
172+
union ionic_dev_cmd cmd = {
173+
.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
174+
.port_setattr.index = 0,
175+
.port_setattr.attr = IONIC_PORT_ATTR_STATE,
176+
.port_setattr.state = state,
177+
};
178+
179+
ionic_dev_cmd_go(idev, &cmd);
180+
}
181+
182+
void ionic_dev_cmd_port_speed(struct ionic_dev *idev, u32 speed)
183+
{
184+
union ionic_dev_cmd cmd = {
185+
.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
186+
.port_setattr.index = 0,
187+
.port_setattr.attr = IONIC_PORT_ATTR_SPEED,
188+
.port_setattr.speed = cpu_to_le32(speed),
189+
};
190+
191+
ionic_dev_cmd_go(idev, &cmd);
192+
}
193+
194+
void ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, u8 an_enable)
195+
{
196+
union ionic_dev_cmd cmd = {
197+
.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
198+
.port_setattr.index = 0,
199+
.port_setattr.attr = IONIC_PORT_ATTR_AUTONEG,
200+
.port_setattr.an_enable = an_enable,
201+
};
202+
203+
ionic_dev_cmd_go(idev, &cmd);
204+
}
205+
206+
void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type)
207+
{
208+
union ionic_dev_cmd cmd = {
209+
.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
210+
.port_setattr.index = 0,
211+
.port_setattr.attr = IONIC_PORT_ATTR_FEC,
212+
.port_setattr.fec_type = fec_type,
213+
};
214+
215+
ionic_dev_cmd_go(idev, &cmd);
216+
}
217+
218+
void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type)
219+
{
220+
union ionic_dev_cmd cmd = {
221+
.port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
222+
.port_setattr.index = 0,
223+
.port_setattr.attr = IONIC_PORT_ATTR_PAUSE,
224+
.port_setattr.pause_type = pause_type,
225+
};
226+
227+
ionic_dev_cmd_go(idev, &cmd);
228+
}

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct ionic_dev {
117117
struct ionic_intr __iomem *intr_ctrl;
118118
u64 __iomem *intr_status;
119119

120+
u32 port_info_sz;
121+
struct ionic_port_info *port_info;
122+
dma_addr_t port_info_pa;
123+
120124
struct ionic_devinfo dev_info;
121125
};
122126

@@ -135,4 +139,13 @@ void ionic_dev_cmd_identify(struct ionic_dev *idev, u8 ver);
135139
void ionic_dev_cmd_init(struct ionic_dev *idev);
136140
void ionic_dev_cmd_reset(struct ionic_dev *idev);
137141

142+
void ionic_dev_cmd_port_identify(struct ionic_dev *idev);
143+
void ionic_dev_cmd_port_init(struct ionic_dev *idev);
144+
void ionic_dev_cmd_port_reset(struct ionic_dev *idev);
145+
void ionic_dev_cmd_port_state(struct ionic_dev *idev, u8 state);
146+
void ionic_dev_cmd_port_speed(struct ionic_dev *idev, u32 speed);
147+
void ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, u8 an_enable);
148+
void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type);
149+
void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type);
150+
138151
#endif /* _IONIC_DEV_H_ */

drivers/net/ethernet/pensando/ionic/ionic_main.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,94 @@ int ionic_reset(struct ionic *ionic)
303303
return err;
304304
}
305305

306+
int ionic_port_identify(struct ionic *ionic)
307+
{
308+
struct ionic_identity *ident = &ionic->ident;
309+
struct ionic_dev *idev = &ionic->idev;
310+
size_t sz;
311+
int err;
312+
313+
mutex_lock(&ionic->dev_cmd_lock);
314+
315+
ionic_dev_cmd_port_identify(idev);
316+
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
317+
if (!err) {
318+
sz = min(sizeof(ident->port), sizeof(idev->dev_cmd_regs->data));
319+
memcpy_fromio(&ident->port, &idev->dev_cmd_regs->data, sz);
320+
}
321+
322+
mutex_unlock(&ionic->dev_cmd_lock);
323+
324+
return err;
325+
}
326+
327+
int ionic_port_init(struct ionic *ionic)
328+
{
329+
struct ionic_identity *ident = &ionic->ident;
330+
struct ionic_dev *idev = &ionic->idev;
331+
size_t sz;
332+
int err;
333+
334+
if (idev->port_info)
335+
return 0;
336+
337+
idev->port_info_sz = ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
338+
idev->port_info = dma_alloc_coherent(ionic->dev, idev->port_info_sz,
339+
&idev->port_info_pa,
340+
GFP_KERNEL);
341+
if (!idev->port_info) {
342+
dev_err(ionic->dev, "Failed to allocate port info, aborting\n");
343+
return -ENOMEM;
344+
}
345+
346+
sz = min(sizeof(ident->port.config), sizeof(idev->dev_cmd_regs->data));
347+
348+
mutex_lock(&ionic->dev_cmd_lock);
349+
350+
memcpy_toio(&idev->dev_cmd_regs->data, &ident->port.config, sz);
351+
ionic_dev_cmd_port_init(idev);
352+
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
353+
354+
ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
355+
(void)ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
356+
357+
mutex_unlock(&ionic->dev_cmd_lock);
358+
if (err) {
359+
dev_err(ionic->dev, "Failed to init port\n");
360+
dma_free_coherent(ionic->dev, idev->port_info_sz,
361+
idev->port_info, idev->port_info_pa);
362+
idev->port_info = NULL;
363+
idev->port_info_pa = 0;
364+
}
365+
366+
return err;
367+
}
368+
369+
int ionic_port_reset(struct ionic *ionic)
370+
{
371+
struct ionic_dev *idev = &ionic->idev;
372+
int err;
373+
374+
if (!idev->port_info)
375+
return 0;
376+
377+
mutex_lock(&ionic->dev_cmd_lock);
378+
ionic_dev_cmd_port_reset(idev);
379+
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
380+
mutex_unlock(&ionic->dev_cmd_lock);
381+
382+
dma_free_coherent(ionic->dev, idev->port_info_sz,
383+
idev->port_info, idev->port_info_pa);
384+
385+
idev->port_info = NULL;
386+
idev->port_info_pa = 0;
387+
388+
if (err)
389+
dev_err(ionic->dev, "Failed to reset port\n");
390+
391+
return err;
392+
}
393+
306394
static int __init ionic_init_module(void)
307395
{
308396
pr_info("%s %s, ver %s\n",

0 commit comments

Comments
 (0)