É feito no nível elétrico, não por software. Os dois registros que você listou acima, LNK_CAP e LNK_STA, são os que você observou corretamente como "Aqui está o que o link é capaz de fazer" e "Aqui o status atual". Há também SLT_CAP e SLT_STA, o que pode valer a pena, já que é específico para um determinado 'slot' na máquina.
A especificação PCIe define um LTSSM - Treinamento de link e máquina de estado de status. No nível PHY / device, é isso que determina a velocidade máxima que ambos os dispositivos suportam, a largura máxima de link suportada pelos dois dispositivos, e é também onde a inversão de polaridade / pista é manipulada (para facilitar o layout para nós, a especificação permite P / N para ser trocado, etc.).
Os dispositivos enviam conjuntos de símbolos ordenados e conhecidos entre si e o hardware trabalha a partir de 2.5GT / s. Existem comandos de mudança de velocidade que podem ser enviados uns aos outros, e aqui é onde as configurações de equalização do canal também são definidas.
Se você estiver conectando na velocidade errada, é possível que a porta raiz PCIe esteja configurada incorretamente ou que exista um problema de integridade de sinal forçando uma largura de link menor. Na minha experiência, se você estava ligando a 5 GT / s em vez de 8 GT / s, isso é mais um problema de SI - ligar a x4 8 GT / s em vez de x8 8 GT / s parece um problema de configuração, ou talvez adicionar um cartão a um slot que não suporte x8 de largura.
O registro de recursos complexos de raiz (Offset 04h) revelará a largura máxima suportada, que pode ajudar com seus diagnósticos. IIRC, -x irá despejar o primeiro 4K do espaço de configuração, -xx ou -xxx irá descarregar o espaço de configuração estendido do PCIe. Se você despejar todo o seu espaço de configuração aqui / pastebin ele, eu posso vasculhar para você possivelmente, mas o Linux faz um trabalho decente de decodificar o que os registradores fazem.