|
@@ -45,7 +45,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
45
|
45
|
*/
|
46
|
46
|
|
47
|
47
|
/** Maximum number of ports */
|
48
|
|
-#define PHN_MAX_NUM_PORTS 4
|
|
48
|
+#define PHN_MAX_NUM_PORTS 8
|
49
|
49
|
|
50
|
50
|
/** Maximum time to wait for command PEG to initialise
|
51
|
51
|
*
|
|
@@ -154,6 +154,10 @@ struct phantom_nic {
|
154
|
154
|
unsigned long rds_producer_crb;
|
155
|
155
|
/** RX status descriptor consumer CRB offset */
|
156
|
156
|
unsigned long sds_consumer_crb;
|
|
157
|
+ /** RX interrupt mask CRB offset */
|
|
158
|
+ unsigned long sds_irq_mask_crb;
|
|
159
|
+ /** RX interrupts enabled */
|
|
160
|
+ unsigned int sds_irq_enabled;
|
157
|
161
|
|
158
|
162
|
/** RX producer index */
|
159
|
163
|
unsigned int rds_producer_idx;
|
|
@@ -192,6 +196,30 @@ struct phantom_nic {
|
192
|
196
|
struct settings settings;
|
193
|
197
|
};
|
194
|
198
|
|
|
199
|
+/** Interrupt mask registers */
|
|
200
|
+static const unsigned long phantom_irq_mask_reg[PHN_MAX_NUM_PORTS] = {
|
|
201
|
+ UNM_PCIE_IRQ_MASK_F0,
|
|
202
|
+ UNM_PCIE_IRQ_MASK_F1,
|
|
203
|
+ UNM_PCIE_IRQ_MASK_F2,
|
|
204
|
+ UNM_PCIE_IRQ_MASK_F3,
|
|
205
|
+ UNM_PCIE_IRQ_MASK_F4,
|
|
206
|
+ UNM_PCIE_IRQ_MASK_F5,
|
|
207
|
+ UNM_PCIE_IRQ_MASK_F6,
|
|
208
|
+ UNM_PCIE_IRQ_MASK_F7,
|
|
209
|
+};
|
|
210
|
+
|
|
211
|
+/** Interrupt status registers */
|
|
212
|
+static const unsigned long phantom_irq_status_reg[PHN_MAX_NUM_PORTS] = {
|
|
213
|
+ UNM_PCIE_IRQ_STATUS_F0,
|
|
214
|
+ UNM_PCIE_IRQ_STATUS_F1,
|
|
215
|
+ UNM_PCIE_IRQ_STATUS_F2,
|
|
216
|
+ UNM_PCIE_IRQ_STATUS_F3,
|
|
217
|
+ UNM_PCIE_IRQ_STATUS_F4,
|
|
218
|
+ UNM_PCIE_IRQ_STATUS_F5,
|
|
219
|
+ UNM_PCIE_IRQ_STATUS_F6,
|
|
220
|
+ UNM_PCIE_IRQ_STATUS_F7,
|
|
221
|
+};
|
|
222
|
+
|
195
|
223
|
/***************************************************************************
|
196
|
224
|
*
|
197
|
225
|
* CRB register access
|
|
@@ -664,10 +692,13 @@ static int phantom_create_rx_ctx ( struct phantom_nic *phantom ) {
|
664
|
692
|
le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
|
665
|
693
|
phantom->rds_producer_crb =
|
666
|
694
|
( UNM_CAM_RAM +
|
667
|
|
- le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ));
|
|
695
|
+ le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ) );
|
668
|
696
|
phantom->sds_consumer_crb =
|
669
|
697
|
( UNM_CAM_RAM +
|
670
|
|
- le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ));
|
|
698
|
+ le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ) );
|
|
699
|
+ phantom->sds_irq_mask_crb =
|
|
700
|
+ ( UNM_CAM_RAM +
|
|
701
|
+ le32_to_cpu ( buf->cardrsp.sds.interrupt_crb ) );
|
671
|
702
|
|
672
|
703
|
DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys "
|
673
|
704
|
"%02x virt %02x)\n", phantom, phantom->rx_context_id,
|
|
@@ -678,6 +709,8 @@ static int phantom_create_rx_ctx ( struct phantom_nic *phantom ) {
|
678
|
709
|
phantom, phantom->rds_producer_crb );
|
679
|
710
|
DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n",
|
680
|
711
|
phantom, phantom->sds_consumer_crb );
|
|
712
|
+ DBGC ( phantom, "Phantom %p SDS interrupt mask CRB is %08lx\n",
|
|
713
|
+ phantom, phantom->sds_irq_mask_crb );
|
681
|
714
|
|
682
|
715
|
out:
|
683
|
716
|
free_dma ( buf, sizeof ( *buf ) );
|
|
@@ -1263,6 +1296,8 @@ static int phantom_transmit ( struct net_device *netdev,
|
1263
|
1296
|
static void phantom_poll ( struct net_device *netdev ) {
|
1264
|
1297
|
struct phantom_nic *phantom = netdev_priv ( netdev );
|
1265
|
1298
|
struct io_buffer *iobuf;
|
|
1299
|
+ unsigned int irq_vector;
|
|
1300
|
+ unsigned int irq_state;
|
1266
|
1301
|
unsigned int cds_consumer_idx;
|
1267
|
1302
|
unsigned int raw_new_cds_consumer_idx;
|
1268
|
1303
|
unsigned int new_cds_consumer_idx;
|
|
@@ -1272,6 +1307,32 @@ static void phantom_poll ( struct net_device *netdev ) {
|
1272
|
1307
|
unsigned int sds_handle;
|
1273
|
1308
|
unsigned int sds_opcode;
|
1274
|
1309
|
|
|
1310
|
+ /* Occasionally poll the link state */
|
|
1311
|
+ if ( phantom->link_poll_timer-- == 0 ) {
|
|
1312
|
+ phantom_poll_link_state ( netdev );
|
|
1313
|
+ /* Reset the link poll timer */
|
|
1314
|
+ phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
|
|
1315
|
+ }
|
|
1316
|
+
|
|
1317
|
+ /* Check for interrupts */
|
|
1318
|
+ if ( phantom->sds_irq_enabled ) {
|
|
1319
|
+
|
|
1320
|
+ /* Do nothing unless an interrupt is asserted */
|
|
1321
|
+ irq_vector = phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
|
|
1322
|
+ if ( ! ( irq_vector & UNM_PCIE_IRQ_VECTOR_BIT( phantom->port )))
|
|
1323
|
+ return;
|
|
1324
|
+
|
|
1325
|
+ /* Do nothing unless interrupt state machine has stabilised */
|
|
1326
|
+ irq_state = phantom_readl ( phantom, UNM_PCIE_IRQ_STATE );
|
|
1327
|
+ if ( ! UNM_PCIE_IRQ_STATE_TRIGGERED ( irq_state ) )
|
|
1328
|
+ return;
|
|
1329
|
+
|
|
1330
|
+ /* Acknowledge interrupt */
|
|
1331
|
+ phantom_writel ( phantom, UNM_PCIE_IRQ_STATUS_MAGIC,
|
|
1332
|
+ phantom_irq_status_reg[phantom->port] );
|
|
1333
|
+ phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
|
|
1334
|
+ }
|
|
1335
|
+
|
1275
|
1336
|
/* Check for TX completions */
|
1276
|
1337
|
cds_consumer_idx = phantom->cds_consumer_idx;
|
1277
|
1338
|
raw_new_cds_consumer_idx = phantom->desc->cmd_cons;
|
|
@@ -1361,13 +1422,6 @@ static void phantom_poll ( struct net_device *netdev ) {
|
1361
|
1422
|
|
1362
|
1423
|
/* Refill the RX descriptor ring */
|
1363
|
1424
|
phantom_refill_rx_ring ( netdev );
|
1364
|
|
-
|
1365
|
|
- /* Occasionally poll the link state */
|
1366
|
|
- if ( phantom->link_poll_timer-- == 0 ) {
|
1367
|
|
- phantom_poll_link_state ( netdev );
|
1368
|
|
- /* Reset the link poll timer */
|
1369
|
|
- phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
|
1370
|
|
- }
|
1371
|
1425
|
}
|
1372
|
1426
|
|
1373
|
1427
|
/**
|
|
@@ -1378,16 +1432,12 @@ static void phantom_poll ( struct net_device *netdev ) {
|
1378
|
1432
|
*/
|
1379
|
1433
|
static void phantom_irq ( struct net_device *netdev, int enable ) {
|
1380
|
1434
|
struct phantom_nic *phantom = netdev_priv ( netdev );
|
1381
|
|
- static const unsigned long sw_int_mask_reg[PHN_MAX_NUM_PORTS] = {
|
1382
|
|
- UNM_NIC_REG_SW_INT_MASK_0,
|
1383
|
|
- UNM_NIC_REG_SW_INT_MASK_1,
|
1384
|
|
- UNM_NIC_REG_SW_INT_MASK_2,
|
1385
|
|
- UNM_NIC_REG_SW_INT_MASK_3
|
1386
|
|
- };
|
1387
|
1435
|
|
1388
|
|
- phantom_writel ( phantom,
|
1389
|
|
- ( enable ? 1 : 0 ),
|
1390
|
|
- sw_int_mask_reg[phantom->port] );
|
|
1436
|
+ phantom_writel ( phantom, ( enable ? 1 : 0 ),
|
|
1437
|
+ phantom->sds_irq_mask_crb );
|
|
1438
|
+ phantom_writel ( phantom, UNM_PCIE_IRQ_MASK_MAGIC,
|
|
1439
|
+ phantom_irq_mask_reg[phantom->port] );
|
|
1440
|
+ phantom->sds_irq_enabled = enable;
|
1391
|
1441
|
}
|
1392
|
1442
|
|
1393
|
1443
|
/** Phantom net device operations */
|